From 183ca5a5823619158f947803a2ae376b1fd85377 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 5 Oct 2015 23:12:32 -0700 Subject: [PATCH 01/60] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/e83090296c16 Author: Yi-Fan Liao Desc: Merge pull request #32229 from ferjm/bug1211367.fxaassertionkeys.tv Bug 1211367 - Add getAssertion and getKeys to Firefox Accounts client. r=yifan ======== https://hg.mozilla.org/integration/gaia-central/rev/f28082794508 Author: Fernando Jiménez Moreno Desc: Bug 1211367 - Add getAssertion and getKeys to Firefox Accounts client. r=yifan --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index a72fcf6cc665..5ddf2d08a8ac 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "60cdaa3d3424db3432dc903e7f9c6c8fa099c06d", + "git_revision": "8c58d628dcccdfccd238d5f128dfce37795a981f", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "1de2dfa13b0b91c293111198011353c7bb86242d", + "revision": "e83090296c16cd09dc5ed5bb2de157547beba4c9", "repo_path": "integration/gaia-central" } From 95da073dc7e36ff6c581bb1d1b2af57756f13b68 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 5 Oct 2015 23:15:40 -0700 Subject: [PATCH 02/60] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index fa381995fd49..f3ac2b4a8475 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index e6d93db6e115..c3a6f3fafc78 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 17ed8e3480e2..434079de15ff 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index b85821e6120e..4eef3aa971eb 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index e07de16b1559..8f829599e9ff 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 1baf3418253a..335062e5849f 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 17ed8e3480e2..434079de15ff 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index af584905fa3f..7cd005a3fab7 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4-kk/sources.xml b/b2g/config/nexus-4-kk/sources.xml index cc6f720cd2d8..edc3a358faa9 100644 --- a/b2g/config/nexus-4-kk/sources.xml +++ b/b2g/config/nexus-4-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 671e16d0af60..6f86326fd146 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -18,7 +18,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 5ae9e0c3c5d5..e573739f3389 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 2ff22b7cc9c3c78a5b952b4994a84851bcddfbe8 Mon Sep 17 00:00:00 2001 From: Ben Hsu Date: Sun, 4 Oct 2015 22:51:00 +0800 Subject: [PATCH 03/60] Bug 1147296 - Part 1: Create |Modem| helper object (head.js). r=btseng --- dom/telephony/test/marionette/head.js | 180 +++++++++++------- .../test/marionette/test_modem_switch_tech.js | 4 +- 2 files changed, 117 insertions(+), 67 deletions(-) diff --git a/dom/telephony/test/marionette/head.js b/dom/telephony/test/marionette/head.js index a092585cce58..7536a249e2fb 100644 --- a/dom/telephony/test/marionette/head.js +++ b/dom/telephony/test/marionette/head.js @@ -99,6 +99,121 @@ var emulator = (function() { }; }()); +/** + * Modem Helper + * + * TODO: Should select which modem here to support multi-SIM + */ + +function modemHelperGenerator() { + function Modem(aClientID) { + this.clientID = aClientID; + } + Modem.prototype = { + clientID: 0, + + voiceTypeToTech: function(aVoiceType) { + switch(aVoiceType) { + case "gsm": + case "gprs": + case "edge": + return "gsm"; + + case "umts": + case "hsdpa": + case "hsupa": + case "hspa": + case "hspa+": + return "wcdma"; + + case "is95a": + case "is95b": + case "1xrtt": + return "cdma"; + + case "evdo0": + case "evdoa": + case "evdob": + return "evdo"; + + case "ehrpd": + return "ehrpd"; + + case "lte": + return "lte"; + + default: + return null; + } + }, + + isCDMA: function() { + var mobileConn = navigator.mozMobileConnections[this.clientID]; + var tech = mobileConn && this.voiceTypeToTech(mobileConn.voice.type); + return tech === "cdma" || tech === "evdo" || tech == "ehrpd"; + }, + + isGSM: function() { + var mobileConn = navigator.mozMobileConnections[this.clientID]; + var tech = mobileConn && this.voiceTypeToTech(mobileConn.voice.type); + return tech === "gsm" || tech === "wcdma" || tech === "lte"; + }, + + /** + * @return Promise: + */ + changeTech: function(aTech, aMask) { + let target = navigator.mozMobileConnections[this.clientID]; + + let mask = aMask || { + gsm: "gsm", + wcdma: "gsm/wcdma", + cdma: "cdma", + evdo: "evdo0", + ehrpd: "ehrpd", + lte: "lte" + }[aTech]; + + let waitForExpectedTech = () => { + return new Promise((aResolve, aReject) => { + let listener = aEvent => { + log("MobileConnection[" + this.clientID + "] " + + "received event 'voicechange'"); + if (aTech === this.voiceTypeToTech(target.voice.type)) { + target.removeEventListener("voicechange", listener); + aResolve(); + } + }; + + target.addEventListener("voicechange", listener); + }); + }; + + // TODO: Should select a modem here to support multi-SIM + let changeToExpectedTech = () => { + return Promise.resolve() + .then(() => emulator.runCmd("modem tech " + aTech + " " + mask)) + .then(() => emulator.runCmd("modem tech")) + .then(result => is(result[0], aTech + " " + mask, + "Check modem 'tech/preferred mask'")); + } + + return aTech === this.voiceTypeToTech(target.voice.type) + ? Promise.resolve() + : Promise.all([waitForExpectedTech(), changeToExpectedTech()]); + } + }; + + let modems = []; + for (let i = 0; i < navigator.mozMobileConnections.length; ++i) { + modems.push(new Modem(i)); + } + return modems; +} + +let Modems = modemHelperGenerator(); +let Modem = Modems[0]; + /** * Telephony related helper functions. */ @@ -276,70 +391,6 @@ var emulator = (function() { }); } - /** - * @param aVoiceType - * The voice type of a mobileConnection, which can be obtained from - * |.voice.type|. - * @return A string with format of the emulator voice tech. - */ - function voiceTypeToTech(aVoiceType) { - switch(aVoiceType) { - case "gsm": - case "gprs": - case "edge": - return "gsm"; - - case "umts": - case "hsdpa": - case "hsupa": - case "hspa": - case "hspa+": - return "wcdma"; - - case "is95a": - case "is95b": - case "1xrtt": - return "cdma"; - - case "evdo0": - case "evdoa": - case "evdob": - return "evdo"; - - case "ehrpd": - case "lte": - return "lte"; - - default: - return null; - } - } - - /** - * @return Promise - */ - function changeModemTech(aTech, aPreferredMask) { - let mobileConn = navigator.mozMobileConnections[0]; - - function isTechMatched() { - return aTech === voiceTypeToTech(mobileConn.voice.type); - } - - let promise1 = isTechMatched() ? Promise.resolve() - : waitForEvent(mobileConn, - "voicechange", - isTechMatched); - - let promise2 = Promise.resolve() - .then(() => emulator.runCmd("modem tech " + aTech + " " + aPreferredMask)) - .then(() => emulator.runCmd("modem tech")) - .then(result => is(result[0], - aTech + " " + aPreferredMask, - "Check modem 'tech/preferred mask'")); - - return Promise.all([promise1, promise2]); - } - /** * @return Promise */ @@ -1216,7 +1267,6 @@ var emulator = (function() { this.gWaitForNamedStateEvent = waitForNamedStateEvent; this.gWaitForStateChangeEvent = waitForStateChangeEvent; this.gCheckInitialState = checkInitialState; - this.gChangeModemTech = changeModemTech; this.gClearCalls = clearCalls; this.gOutCallStrPool = outCallStrPool; this.gInCallStrPool = inCallStrPool; diff --git a/dom/telephony/test/marionette/test_modem_switch_tech.js b/dom/telephony/test/marionette/test_modem_switch_tech.js index 565f528ec5c0..7af228cdae4d 100644 --- a/dom/telephony/test/marionette/test_modem_switch_tech.js +++ b/dom/telephony/test/marionette/test_modem_switch_tech.js @@ -39,7 +39,7 @@ var settings = [ startTest(function() { let promise = settings.reduce((aPromise, aSetting) => { - return aPromise.then(() => gChangeModemTech(aSetting.tech, aSetting.mask)); + return aPromise.then(() => Modem.changeTech(aSetting.tech, aSetting.mask)); }, Promise.resolve()); return promise @@ -47,7 +47,7 @@ startTest(function() { .catch(error => ok(false, "Promise reject: " + error)) // Switch to the default modem tech - .then(() => gChangeModemTech("wcdma", "gsm/wcdma")) + .then(() => Modem.changeTech("wcdma", "gsm/wcdma")) .catch(error => ok(false, "Fetal Error: Promise reject: " + error)) .then(finish); From 6a025048641c4de828114047050f612cd55ae979 Mon Sep 17 00:00:00 2001 From: Ben Hsu Date: Fri, 11 Sep 2015 03:07:00 +0800 Subject: [PATCH 04/60] Bug 1147296 - Part 2: Move to telephony command group and support CDMA operations (head.js). r=btseng --- dom/telephony/test/marionette/head.js | 59 +++++++++++++------ .../test/marionette/test_TelephonyUtils.js | 4 +- .../test/marionette/test_consecutive_hold.js | 6 +- .../marionette/test_outgoing_auto_hold.js | 6 +- .../test/marionette/test_outgoing_busy.js | 2 +- 5 files changed, 50 insertions(+), 27 deletions(-) diff --git a/dom/telephony/test/marionette/head.js b/dom/telephony/test/marionette/head.js index 7536a249e2fb..189a8eaf335e 100644 --- a/dom/telephony/test/marionette/head.js +++ b/dom/telephony/test/marionette/head.js @@ -412,7 +412,7 @@ let Modem = Modems[0]; return Promise.all(hangUpPromises) .then(() => { - return emulator.runCmd("gsm clear").then(waitForNoCall); + return emulator.runCmd("telephony clear").then(waitForNoCall); }) .then(waitForNoCall); } @@ -529,7 +529,7 @@ let Modem = Modems[0]; * @return Promise */ function checkEmulatorCallList(expectedCallList) { - return emulator.runCmd("gsm list").then(result => { + return emulator.runCmd("telephony list").then(result => { log("Call list is now: " + result); for (let i = 0; i < expectedCallList.length; ++i) { is(result[i], expectedCallList[i], "emulator calllist"); @@ -582,9 +582,9 @@ let Modem = Modems[0]; return checkEmulatorCallList(callList); } - /** - * Request utility functions. - */ + /**************************************************************************** + **** Request utility functions **** + ****************************************************************************/ /** * Make an outgoing call. @@ -609,7 +609,13 @@ let Modem = Modems[0]; is(outCall.state, "dialing"); is(outCall.serviceId, serviceId); }) - .then(() => waitForNamedStateEvent(outCall, "alerting")); + .then(() => { + // A CDMA call goes to connected state directly when the operator find + // its callee, which makes the "connected" state in CDMA calls behaves + // like the "alerting" state in GSM calls. + let state = Modems[serviceId].isGSM() ? "alerting" : "connected"; + return waitForNamedStateEvent(outCall, state); + }); } /** @@ -632,7 +638,13 @@ let Modem = Modems[0]; is(outCall.id.number, number); is(outCall.state, "dialing"); }) - .then(() => waitForNamedStateEvent(outCall, "alerting")) + .then(() => { + // Similar to function |dial|, a CDMA call directly goes to connected + // state when the operator find its callee. + let state = Modems[outCall.serviceId].isGSM() ? "alerting" + : "connected"; + return waitForNamedStateEvent(outCall, state); + }) .then(() => { is(outCall.emergency, true, "check emergency"); return outCall; @@ -702,19 +714,23 @@ let Modem = Modems[0]; /** * Hold a call. * - * @param call + * @param aCall * A TelephonyCall object. + * @param aWaitForEvent + * Decide whether to wait for the state event. * @return Promise */ - function hold(call) { + function hold(aCall, aWaitForEvent = true) { log("Putting the call on hold."); let promises = []; - promises.push(waitForNamedStateEvent(call, "held")); - promises.push(call.hold()); + if (aWaitForEvent) { + promises.push(waitForNamedStateEvent(aCall, "held")); + } + promises.push(aCall.hold()); - return Promise.all(promises).then(() => call); + return Promise.all(promises).then(() => aCall); } /** @@ -724,7 +740,7 @@ let Modem = Modems[0]; * A TelephonyCall object. * @return Promise */ - function resume(call) { + function resume(call, aWaitForEvent = true) { log("Resuming the held call."); let promises = []; @@ -772,8 +788,10 @@ let Modem = Modems[0]; numberPresentation = numberPresentation || ""; name = name || ""; namePresentation = namePresentation || ""; - emulator.runCmd("gsm call " + number + "," + numberPresentation + "," + name + - "," + namePresentation); + emulator.runCmd("telephony call " + number + + "," + numberPresentation + + "," + name + + "," + namePresentation); return waitForEvent(telephony, "incoming") .then(event => { @@ -798,9 +816,14 @@ let Modem = Modems[0]; function remoteAnswer(call) { log("Remote answering the call: " + call.id.number); - emulator.runCmd("gsm accept " + call.id.number); + emulator.runCmd("telephony accept " + call.id.number); - return waitForNamedStateEvent(call, "connected"); + // A CDMA call goes to connected state directly when the operator find its + // callee, which makes the "connected" state in CDMA calls behaves like the + // "alerting" state in GSM calls, so we don't have to wait for the call to + // change to "connected" state here for CDMA calls. + return Modem.isCDMA() ? Promise.resolve() + : waitForNamedStateEvent(call, "connected"); } /** @@ -813,7 +836,7 @@ let Modem = Modems[0]; function remoteHangUp(call) { log("Remote hanging up the call: " + call.id.number); - emulator.runCmd("gsm cancel " + call.id.number); + emulator.runCmd("telephony cancel " + call.id.number); return waitForNamedStateEvent(call, "disconnected"); } diff --git a/dom/telephony/test/marionette/test_TelephonyUtils.js b/dom/telephony/test/marionette/test_TelephonyUtils.js index 7cecd11b0b00..a0b5c3a0556d 100644 --- a/dom/telephony/test/marionette/test_TelephonyUtils.js +++ b/dom/telephony/test/marionette/test_TelephonyUtils.js @@ -78,7 +78,7 @@ function test_oneCall() { let p = waitForStateChanged(aAllInfo => { return aAllInfo[0].callState === Ci.nsITelephonyService.CALL_STATE_CONNECTED; }); - emulator.runCmd("gsm accept " + number); + emulator.runCmd("telephony accept " + number); return p; }) .then(() => { @@ -87,7 +87,7 @@ function test_oneCall() { }) .then(() => { let p = TelephonyUtils.waitForNoCalls(); - emulator.runCmd("gsm cancel " + number); + emulator.runCmd("telephony cancel " + number); return p; }); } diff --git a/dom/telephony/test/marionette/test_consecutive_hold.js b/dom/telephony/test/marionette/test_consecutive_hold.js index c13f95a9b1ba..c09c179fd1b8 100644 --- a/dom/telephony/test/marionette/test_consecutive_hold.js +++ b/dom/telephony/test/marionette/test_consecutive_hold.js @@ -24,7 +24,7 @@ startTest(function() { // Disable the Hold function of the emulator, then hold the active call, // where the hold request will fail and the call will remain active. - .then(() => emulator.runCmd("gsm disable hold")) + .then(() => emulator.runCmd("telephony disable hold")) .then(() => gHold(inCall)) .then(() => ok(false, "This hold request should be rejected."), () => log("This hold request is rejected as expected.")) @@ -33,7 +33,7 @@ startTest(function() { // Enable the Hold function of the emulator, then hold the active call, // where the hold request should succeed and the call should become held. - .then(() => emulator.runCmd("gsm enable hold")) + .then(() => emulator.runCmd("telephony enable hold")) .then(() => gHold(inCall)) .then(() => log("This hold request is resolved as expected."), () => ok(false, "This hold request should be resolved.")) @@ -47,6 +47,6 @@ startTest(function() { // Clean Up .catch(error => ok(false, "Promise reject: " + error)) - .then(() => emulator.runCmd("gsm enable hold")) + .then(() => emulator.runCmd("telephony enable hold")) .then(finish); }); diff --git a/dom/telephony/test/marionette/test_outgoing_auto_hold.js b/dom/telephony/test/marionette/test_outgoing_auto_hold.js index af07835d3063..7dca375920bd 100644 --- a/dom/telephony/test/marionette/test_outgoing_auto_hold.js +++ b/dom/telephony/test/marionette/test_outgoing_auto_hold.js @@ -37,7 +37,7 @@ function testAutoHoldCallFailed() { const callNumber2 = "0900000012"; return Promise.resolve() - .then(() => emulator.runCmd("gsm disable hold")) + .then(() => emulator.runCmd("telephony disable hold")) .then(() => gDial(callNumber1)) .then(call => { outCall1 = call; }) .then(() => gRemoteAnswer(outCall1)) @@ -51,7 +51,7 @@ function testAutoHoldCallFailed() { return gRemoteHangUpCalls([outCall2]); }, () => log("The second |dial()| is rejected as expected.")) .then(() => gRemoteHangUpCalls([outCall1])) - .then(() => emulator.runCmd("gsm enable hold")); + .then(() => emulator.runCmd("telephony enable hold")); } function testAutoHoldConferenceCall() { @@ -87,7 +87,7 @@ startTest(function() { .then(() => testAutoHoldConferenceCall()) .catch(error => { ok(false, "Promise reject: " + error); - emulator.runCmd("gsm enable hold"); + emulator.runCmd("telephony enable hold"); }) .then(finish); }); diff --git a/dom/telephony/test/marionette/test_outgoing_busy.js b/dom/telephony/test/marionette/test_outgoing_busy.js index 5c48acda8b25..1a77316db233 100644 --- a/dom/telephony/test/marionette/test_outgoing_busy.js +++ b/dom/telephony/test/marionette/test_outgoing_busy.js @@ -19,7 +19,7 @@ startTest(function() { is(event.call.error.name, "BusyError"); is(event.call.disconnectedReason, "Busy"); }); - let p2 = emulator.runCmd("gsm busy " + outNumber); + let p2 = emulator.runCmd("telephony busy " + outNumber); return Promise.all([p1, p2]); }) .then(() => gCheckAll(null, [], "", [], [])) From 19f1483200e01924176d2f3b06a6d62b4ef92002 Mon Sep 17 00:00:00 2001 From: Ben Hsu Date: Sun, 4 Oct 2015 22:52:00 +0800 Subject: [PATCH 05/60] Bug 1147296 - Part 3: Introduce a new check function for both GSM and CDMA (head.js). r=btseng --- dom/telephony/test/marionette/head.js | 165 ++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/dom/telephony/test/marionette/head.js b/dom/telephony/test/marionette/head.js index 189a8eaf335e..ceac61f65cae 100644 --- a/dom/telephony/test/marionette/head.js +++ b/dom/telephony/test/marionette/head.js @@ -474,6 +474,11 @@ let Modem = Modems[0]; checkState(null, [], "", []); } + + /**************************************************************************** + **** Check Functions **** + ****************************************************************************/ + /** * Convenient helper to compare two call lists (order is not important). */ @@ -582,6 +587,166 @@ let Modem = Modems[0]; return checkEmulatorCallList(callList); } + /** + * The factory function for creating an expected call. + * + * @param aReference + * The reference of the telephonyCall object. + * @param aNumber + * The call number. + * @param aConference + * Shows whether the call belongs to the conference. + * @param aDirection + * The direction of the call, "in" for inbound, and "out" for outbound. + * @param aState + * The expected state of the call. + * @param aEmulatorState + * The state logged in emulator now, may be different from aState. + * @param aDisconnectedReason + * The disconnected reason if the call becomed disconnected. + */ + function createExptectedCall(aReference, aNumber, aConference, aDirection, + aState, aEmulatorState, aDisconnectedReason) { + return { + reference: aReference, + number: aNumber, + conference: aConference, + direction: aDirection, + state: aState, + emulatorState: aEmulatorState, + disconnectedReason: aDisconnectedReason + }; + } + + /** + * Check telephony.active + * + * @param aExpectedCalls + * An array of expected calls. + * @param aExpectedCallsInConference + * An array of expected calls in the conference. + */ + function checkActive(aExpectedCalls, aExpectedCallsInConference) { + // Get the active call + let calls = aExpectedCalls && aExpectedCalls.filter(aExpectedCall => { + return aExpectedCall.state === "connected" || + aExpectedCall.state === "alerting" || + aExpectedCall.state === "dialing"; + }); + + ok(calls.length < 2, "Too many actives call in telephony.calls"); + let activeCall = calls.length ? calls[0].reference : null; + + // Get the active conference + let callsInConference = aExpectedCallsInConference || []; + let activeConference = callsInConference.length && + callsInConference[0].state === "connected" + ? navigator.mozTelephony.conferenceGroup + : null; + + // Check telephony.active + ok(!(activeCall && activeConference), + "An active call cannot coexist with an active conference call."); + is(telephony.active, activeCall || activeConference, "check Active"); + } + + /** + * Check whether the data in telephony and emulator meets our expectation. + * + * NOTE: Conference call is not supported in this function yet, so related + * checks are skipped. + * + * Fulfill params: + * { + * reference, -- the reference of the call object instance. + * number, -- the call number. + * conference, -- shows whether it belongs to the conference. + * direction, -- "in" for inbound, and "out" for outbound. + * state, -- the call state. + * emulatorState, -- the call state logged in emulator now. + * disconnectedReason, -- the disconnected reason of a disconnected call. + * } + * + * @param aExpectedCalls + * An array of call records. + * @return Promise + */ + function equals(aExpectedCalls) { + // Classify calls + let callsInTelephony = []; + let CallsInConference = []; + + aExpectedCalls.forEach(function(aCall) { + if (aCall.state === "disconnected") { + is(aCall.disconnectedReason, + aCall.reference.disconnectedReason, + "Check disconnectedReason"); + return; + } + + if (aCall.conference) { + CallsInConference.push(aCall); + return; + } + + callsInTelephony.push(aCall); + ok(!aCall.secondId, "For a telephony call, the secondId must be null"); + }); + + // Check the active connection + checkActive(callsInTelephony, CallsInConference); + + // Check telephony.calls + is(telephony.calls.length, + callsInTelephony.length, + "Check telephony.calls.length"); + + callsInTelephony.forEach(aExpectedCall => { + let number = aExpectedCall.number; + let call = telephony.calls.find(aCall => aCall.id.number === number); + if (!call) { + ok(false, "telephony.calls lost the call(number: " + number + ")"); + return; + } + + is(call, aExpectedCall.reference, + "Check the object reference of number:" + number); + + is(call.state, aExpectedCall.state, + "Check call.state of number:" + number); + }); + + // Check conference.calls + // NOTE: This function doesn't support conference call now, so the length of + // |CallsInConference| should be 0, and the conference state shoul be "". + is(conference.state, "", "Conference call is not supported yet."); + is(CallsInConference.length, 0, "Conference call is not supported yet."); + + // Check the emulator call list + // NOTE: Conference is not supported yet, so |CallsInConference| is ignored. + let strings = callsInTelephony.map(aCall => { + // The emulator doesn't have records for disconnected calls. + if (aCall.emulatorState === "disconnected") { + return null; + } + + let state = { + alerting: "ringing", + connected: "active", + held: "held", + incoming: "incoming" + }[aCall.state]; + + state = aCall.emulatorState || state; + let prefix = (aCall.direction === "in") ? "inbound from " + : "outbound to "; + + return state ? (prefix + aCall.number + " : " + state) : null; + }); + + return checkEmulatorCallList(strings.filter(aString => aString)); + } + /**************************************************************************** **** Request utility functions **** ****************************************************************************/ From a7067ca7e08337815aaef4bac324ec1f29535df6 Mon Sep 17 00:00:00 2001 From: Ben Hsu Date: Fri, 11 Sep 2015 03:09:00 +0800 Subject: [PATCH 06/60] Bug 1147296 - Part 4: Expose new functions (head.js). r=btseng --- dom/telephony/test/marionette/head.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dom/telephony/test/marionette/head.js b/dom/telephony/test/marionette/head.js index ceac61f65cae..b95ddf8c7e15 100644 --- a/dom/telephony/test/marionette/head.js +++ b/dom/telephony/test/marionette/head.js @@ -1482,6 +1482,25 @@ let Modem = Modems[0]; this.gSetupConference = setupConference; this.gSetRadioEnabled = setRadioEnabled; this.gSetRadioEnabledAll = setRadioEnabledAll; + + // Telephony helper + this.TelephonyHelper = { + dial: dial, + answer: answer, + hangUp: hangUp, + hold: hold, + resume: resume, + equals: equals, + createExptectedCall: createExptectedCall + }; + + // Remote Utils, TODO: This should be an array for multi-SIM scenarios + this.Remotes = [{ + dial: remoteDial, + answer: remoteAnswer, + hangUp: remoteHangUp + }]; + this.Remote = this.Remotes[0]; }()); function _startTest(permissions, test) { From 3eeadf2fdf53137d40025d682643e943d9698417 Mon Sep 17 00:00:00 2001 From: Ben Hsu Date: Fri, 25 Sep 2015 12:57:59 +0800 Subject: [PATCH 07/60] Bug 1147296 - Part 5: Replace two testcases (Testcase). r=btseng --HG-- rename : dom/telephony/test/marionette/test_incoming_basic_operations.js => dom/telephony/test/marionette/test_gsm_cdma_incoming_basic_operations.js rename : dom/telephony/test/marionette/test_outgoing_basic_operations.js => dom/telephony/test/marionette/test_gsm_cdma_outgoing_basic_operations.js --- dom/telephony/test/marionette/manifest.ini | 5 +- ...test_gsm_cdma_incoming_basic_operations.js | 170 +++++++++++++++++ ...test_gsm_cdma_outgoing_basic_operations.js | 174 ++++++++++++++++++ .../test_incoming_basic_operations.js | 123 ------------- .../test_outgoing_basic_operations.js | 123 ------------- 5 files changed, 347 insertions(+), 248 deletions(-) create mode 100644 dom/telephony/test/marionette/test_gsm_cdma_incoming_basic_operations.js create mode 100644 dom/telephony/test/marionette/test_gsm_cdma_outgoing_basic_operations.js delete mode 100644 dom/telephony/test/marionette/test_incoming_basic_operations.js delete mode 100644 dom/telephony/test/marionette/test_outgoing_basic_operations.js diff --git a/dom/telephony/test/marionette/manifest.ini b/dom/telephony/test/marionette/manifest.ini index 228778623bc1..7e83e675340d 100644 --- a/dom/telephony/test/marionette/manifest.ini +++ b/dom/telephony/test/marionette/manifest.ini @@ -24,6 +24,8 @@ qemu = true [test_dtmf.js] [test_emergency.js] [test_emergency_label.js] +[test_gsm_cdma_incoming_basic_operations.js] +[test_gsm_cdma_outgoing_basic_operations.js] [test_incall_mmi_call_hold.js] [test_incall_mmi_call_waiting.js] [test_incall_mmi_conference.js] @@ -31,7 +33,6 @@ qemu = true [test_incoming_already_connected.js] [test_incoming_already_held.js] [test_incoming_answer_hangup_oncallschanged.js] -[test_incoming_basic_operations.js] [test_incoming_onstatechange.js] [test_mmi_call_barring.js] [test_mmi_call_forwarding.js] @@ -52,7 +53,6 @@ qemu = true [test_outgoing_answer_radio_off.js] [test_outgoing_auto_hold.js] [test_outgoing_badNumber.js] -[test_outgoing_basic_operations.js] [test_outgoing_busy.js] [test_outgoing_from_stk.js] [test_outgoing_onstatechange.js] @@ -64,3 +64,4 @@ qemu = true [test_system_message_telephony_call_ended.js] [test_TelephonyUtils.js] [test_temporary_clir.js] + diff --git a/dom/telephony/test/marionette/test_gsm_cdma_incoming_basic_operations.js b/dom/telephony/test/marionette/test_gsm_cdma_incoming_basic_operations.js new file mode 100644 index 000000000000..cf4fe6f60c9f --- /dev/null +++ b/dom/telephony/test/marionette/test_gsm_cdma_incoming_basic_operations.js @@ -0,0 +1,170 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 90000; +MARIONETTE_HEAD_JS = 'head.js'; + +/****************************************************************************** + **** Basic Operations **** + ******************************************************************************/ + +const IncomingNumber = "1111110000"; + +function exptectedCall(aCall, aState, aEmulatorState = null) { + let disconnectedReason = aState === "disconnected" ? "NormalCallClearing" + : null; + + return TelephonyHelper.createExptectedCall(aCall, IncomingNumber, false, + "in", aState, aEmulatorState, + disconnectedReason); +} + +function incoming(aNumber) { + let ret; + return Remote.dial(aNumber) + .then(call => ret = call) + .then(() => TelephonyHelper.equals([exptectedCall(ret, "incoming")])) + .then(() => ret); +} + +function answer(aCall) { + let call = exptectedCall(aCall, "connected"); + return TelephonyHelper.answer(aCall) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +function hold(aCall) { + // Since a CDMA call doesn't have any notification for its state changing to + // "held" state, a telephonyCall is still remains in "connected" state when + // the call actually goes to "held" state, and we shouldn't wait for the state + // change event here. + let state = Modem.isGSM() ? "held" : "connected"; + let call = exptectedCall(aCall, state,"held"); + return TelephonyHelper.hold(aCall, Modem.isGSM()) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +function resume(aCall) { + // Similar to the hold case, there is no notification for a CDMA call's state + // change. Besides, a CDMA call still remains in "connected" state here, so we + // have to use |hold()| function here to resume the call. Otherwise, if we use + // |resume()| function, we'll get an invalid state error. + let call = exptectedCall(aCall, "connected"); + return Modem.isGSM() ? TelephonyHelper.resume(aCall) + : TelephonyHelper.hold(aCall, false) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +function hangUp(aCall) { + let call = exptectedCall(aCall, "disconnected"); + return TelephonyHelper.hangUp(aCall) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +function remoteHangUp(aCall) { + let call = exptectedCall(aCall, "disconnected"); + return Remote.hangUp(aCall) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +/****************************************************************************** + **** Testcases **** + ******************************************************************************/ + +function testIncomingReject() { + log("= testIncomingReject ="); + return incoming(IncomingNumber) + .then(call => hangUp(call)); +} + +function testIncomingCancel() { + log("= testIncomingCancel ="); + return incoming(IncomingNumber) + .then(call => remoteHangUp(call)); +} + +function testIncomingAnswerHangUp() { + log("= testIncomingAnswerHangUp ="); + return incoming(IncomingNumber) + .then(call => answer(call)) + .then(call => hangUp(call)); +} + +function testIncomingAnswerRemoteHangUp() { + log("= testIncomingAnswerRemoteHangUp ="); + return incoming(IncomingNumber) + .then(call => answer(call)) + .then(call => remoteHangUp(call)); +} + +function testIncomingAnswerHoldHangUp() { + log("= testIncomingAnswerHoldHangUp ="); + return incoming(IncomingNumber) + .then(call => answer(call)) + .then(call => hold(call)) + .then(call => hangUp(call)); +} + +function testIncomingAnswerHoldRemoteHangUp() { + log("= testIncomingAnswerHoldRemoteHangUp ="); + return incoming(IncomingNumber) + .then(call => answer(call)) + .then(call => hold(call)) + .then(call => remoteHangUp(call)); +} + +function testIncomingAnswerHoldResumeHangUp() { + log("= testIncomingAnswerHoldResumeHangUp ="); + return incoming(IncomingNumber) + .then(call => answer(call)) + .then(call => hold(call)) + .then(call => resume(call)) + .then(call => hangUp(call)); +} + +function testIncomingAnswerHoldResumeRemoteHangUp() { + log("= testIncomingAnswerHoldResumeRemoteHangUp ="); + return incoming(IncomingNumber) + .then(call => answer(call)) + .then(call => hold(call)) + .then(call => resume(call)) + .then(call => remoteHangUp(call)); +} + +/****************************************************************************** + **** Test Launcher **** + ******************************************************************************/ + +function runTestSuite(aTech, aTechMask) { + return Promise.resolve() + // Setup Environment + .then(() => Modem.changeTech(aTech, aTechMask)) + + // Tests + .then(() => testIncomingReject()) + .then(() => testIncomingCancel()) + .then(() => testIncomingAnswerHangUp()) + .then(() => testIncomingAnswerRemoteHangUp()) + .then(() => testIncomingAnswerHoldHangUp()) + .then(() => testIncomingAnswerHoldRemoteHangUp()) + .then(() => testIncomingAnswerHoldResumeHangUp()) + .then(() => testIncomingAnswerHoldResumeRemoteHangUp()) + + // Restore Environment + .then(() => Modem.changeTech("wcdma")); +} + +startTest(function() { + return Promise.resolve() + .then(() => runTestSuite("cdma")) + .then(() => runTestSuite("wcdma")) + + .catch(error => ok(false, "Promise reject: " + error)) + .then(finish); +}); + diff --git a/dom/telephony/test/marionette/test_gsm_cdma_outgoing_basic_operations.js b/dom/telephony/test/marionette/test_gsm_cdma_outgoing_basic_operations.js new file mode 100644 index 000000000000..b53f4478c4f9 --- /dev/null +++ b/dom/telephony/test/marionette/test_gsm_cdma_outgoing_basic_operations.js @@ -0,0 +1,174 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 90000; +MARIONETTE_HEAD_JS = 'head.js'; + +/****************************************************************************** + **** Basic Operations **** + ******************************************************************************/ + +const OutgoingNumber = "5555551111"; + +function exptectedCall(aCall, aState, aEmulatorState = null) { + let disconnectedReason = aState === "disconnected" ? "NormalCallClearing" + : null; + + return TelephonyHelper.createExptectedCall(aCall, OutgoingNumber, false, + "out", aState, aEmulatorState, + disconnectedReason); +} + +function outgoing(aNumber) { + let ret; + + // Since a CDMA call doesn't have "alerting" state, it directly goes to + // "connected" state instead. + let state = Modem.isCDMA() ? "connected" : "alerting"; + return TelephonyHelper.dial(aNumber) + .then(call => ret = call) + .then(() => TelephonyHelper.equals([exptectedCall(ret, state)])) + .then(() => ret); +} + +function remoteAnswer(aCall) { + let call = exptectedCall(aCall, "connected"); + return Remote.answer(aCall) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +function hold(aCall) { + // Since a CDMA call doesn't have any notification for its state changing to + // "held" state, a telephonyCall is still remains in "connected" state when + // the call actually goes to "held" state, and we shouldn't wait for the state + // change event here. + let state = Modem.isGSM() ? "held" : "connected"; + let call = exptectedCall(aCall, state, "held"); + return TelephonyHelper.hold(aCall, Modem.isGSM()) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +function resume(aCall) { + // Similar to the hold case, there is no notification for a CDMA call's state + // change. Besides, a CDMA call still remains in "connected" state here, so we + // have to use |hold()| function here to resume the call. Otherwise, if we use + // |resume()| function, we'll get an invalid state error. + let call = exptectedCall(aCall, "connected"); + return Modem.isGSM() ? TelephonyHelper.resume(aCall) + : TelephonyHelper.hold(aCall, false) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +function hangUp(aCall) { + let call = exptectedCall(aCall, "disconnected"); + return TelephonyHelper.hangUp(aCall) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +function remoteHangUp(aCall) { + let call = exptectedCall(aCall, "disconnected"); + return Remote.hangUp(aCall) + .then(() => TelephonyHelper.equals([call])) + .then(() => aCall); +} + +/****************************************************************************** + **** Testcases **** + ******************************************************************************/ + +function testOutgoingReject() { + log("= testOutgoingReject ="); + return outgoing(OutgoingNumber) + .then(call => remoteHangUp(call)); +} + +function testOutgoingCancel() { + log("= testOutgoingCancel ="); + return outgoing(OutgoingNumber) + .then(call => hangUp(call)); +} + +function testOutgoingAnswerHangUp() { + log("= testOutgoingAnswerHangUp ="); + return outgoing(OutgoingNumber) + .then(call => remoteAnswer(call)) + .then(call => hangUp(call)); +} + +function testOutgoingAnswerRemoteHangUp() { + log("= testOutgoingAnswerRemoteHangUp ="); + return outgoing(OutgoingNumber) + .then(call => remoteAnswer(call)) + .then(call => remoteHangUp(call)); +} + +function testOutgoingAnswerHoldHangUp() { + log("= testOutgoingAnswerHoldHangUp ="); + return outgoing(OutgoingNumber) + .then(call => remoteAnswer(call)) + .then(call => hold(call)) + .then(call => hangUp(call)); +} + +function testOutgoingAnswerHoldRemoteHangUp() { + log("= testOutgoingAnswerHoldRemoteHangUp ="); + return outgoing(OutgoingNumber) + .then(call => remoteAnswer(call)) + .then(call => hold(call)) + .then(call => remoteHangUp(call)); +} + +function testOutgoingAnswerHoldResumeHangUp() { + log("= testOutgoingAnswerHoldResumeHangUp ="); + return outgoing(OutgoingNumber) + .then(call => remoteAnswer(call)) + .then(call => hold(call)) + .then(call => resume(call)) + .then(call => hangUp(call)); +} + +function testOutgoingAnswerHoldResumeRemoteHangUp() { + log("= testOutgoingAnswerHoldResumeRemoteHangUp ="); + return outgoing(OutgoingNumber) + .then(call => remoteAnswer(call)) + .then(call => hold(call)) + .then(call => resume(call)) + .then(call => remoteHangUp(call)); +} + +/******************************************************************************/ +/*** Test Launcher ***/ +/******************************************************************************/ + +function runTestSuite(aTech, aTechMask) { + return Promise.resolve() + // Setup Environment + .then(() => Modem.changeTech(aTech, aTechMask)) + + // Tests + .then(() => testOutgoingReject()) + .then(() => testOutgoingCancel()) + .then(() => testOutgoingAnswerHangUp()) + .then(() => testOutgoingAnswerRemoteHangUp()) + .then(() => testOutgoingAnswerHoldHangUp()) + .then(() => testOutgoingAnswerHoldRemoteHangUp()) + .then(() => testOutgoingAnswerHoldResumeHangUp()) + .then(() => testOutgoingAnswerHoldResumeRemoteHangUp()) + + // Restore Environment + .then(() => Modem.changeTech("wcdma")); +} + +startTest(function() { + return Promise.resolve() + .then(() => runTestSuite("cdma")) + .then(() => runTestSuite("wcdma")) + + .catch(error => ok(false, "Promise reject: " + error)) + .then(finish); +}); + diff --git a/dom/telephony/test/marionette/test_incoming_basic_operations.js b/dom/telephony/test/marionette/test_incoming_basic_operations.js deleted file mode 100644 index 037df93f2d88..000000000000 --- a/dom/telephony/test/marionette/test_incoming_basic_operations.js +++ /dev/null @@ -1,123 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 90000; -MARIONETTE_HEAD_JS = 'head.js'; - -const inNumber = "5555552222"; -const inInfo = gInCallStrPool(inNumber); -var inCall; - -function incoming() { - return gRemoteDial(inNumber) - .then(call => inCall = call) - .then(() => gCheckAll(null, [inCall], "", [], [inInfo.incoming])) - .then(() => is(inCall.disconnectedReason, null)); -} - -function answer() { - return gAnswer(inCall) - .then(() => gCheckAll(inCall, [inCall], "", [], [inInfo.active])) - .then(() => is(inCall.disconnectedReason, null)); -} - -function hold() { - return gHold(inCall) - .then(() => gCheckAll(null, [inCall], "", [], [inInfo.held])) - .then(() => is(inCall.disconnectedReason, null)); -} - -function resume() { - return gResume(inCall) - .then(() => gCheckAll(inCall, [inCall], "", [], [inInfo.active])) - .then(() => is(inCall.disconnectedReason, null)); -} - -function hangUp() { - return gHangUp(inCall) - .then(() => gCheckAll(null, [], "", [], [])) - .then(() => is(inCall.disconnectedReason, "NormalCallClearing")); -} - -function remoteHangUp() { - return gRemoteHangUp(inCall) - .then(() => gCheckAll(null, [], "", [], [])) - .then(() => is(inCall.disconnectedReason, "NormalCallClearing")); -} - -// Test cases. - -function testIncomingReject() { - log("= testIncomingReject ="); - return incoming() - .then(() => hangUp()); -} - -function testIncomingCancel() { - log("= testIncomingCancel ="); - return incoming() - .then(() => remoteHangUp()); -} - -function testIncomingAnswerHangUp() { - log("= testIncomingAnswerHangUp ="); - return incoming() - .then(() => answer()) - .then(() => hangUp()); -} - -function testIncomingAnswerRemoteHangUp() { - log("= testIncomingAnswerRemoteHangUp ="); - return incoming() - .then(() => answer()) - .then(() => remoteHangUp()); -} - -function testIncomingAnswerHoldHangUp() { - log("= testIncomingAnswerHoldHangUp ="); - return incoming() - .then(() => answer()) - .then(() => hold()) - .then(() => hangUp()); -} - -function testIncomingAnswerHoldRemoteHangUp() { - log("= testIncomingAnswerHoldRemoteHangUp ="); - return incoming() - .then(() => answer()) - .then(() => hold()) - .then(() => remoteHangUp()); -} - -function testIncomingAnswerHoldResumeHangUp() { - log("= testIncomingAnswerHoldResumeHangUp ="); - return incoming() - .then(() => answer()) - .then(() => hold()) - .then(() => resume()) - .then(() => hangUp()); -} - -function testIncomingAnswerHoldResumeRemoteHangUp() { - log("= testIncomingAnswerHoldResumeRemoteHangUp ="); - return incoming() - .then(() => answer()) - .then(() => hold()) - .then(() => resume()) - .then(() => remoteHangUp()); -} - -startTest(function() { - Promise.resolve() - .then(() => testIncomingReject()) - .then(() => testIncomingCancel()) - .then(() => testIncomingAnswerHangUp()) - .then(() => testIncomingAnswerRemoteHangUp()) - .then(() => testIncomingAnswerHoldHangUp()) - .then(() => testIncomingAnswerHoldRemoteHangUp()) - .then(() => testIncomingAnswerHoldResumeHangUp()) - .then(() => testIncomingAnswerHoldResumeRemoteHangUp()) - - .catch(error => ok(false, "Promise reject: " + error)) - .then(finish); -}); diff --git a/dom/telephony/test/marionette/test_outgoing_basic_operations.js b/dom/telephony/test/marionette/test_outgoing_basic_operations.js deleted file mode 100644 index 97ae31f669d0..000000000000 --- a/dom/telephony/test/marionette/test_outgoing_basic_operations.js +++ /dev/null @@ -1,123 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 90000; -MARIONETTE_HEAD_JS = 'head.js'; - -const outNumber = "5555551111"; -const outInfo = gOutCallStrPool(outNumber); -var outCall; - -function outgoing() { - return gDial(outNumber) - .then(call => outCall = call) - .then(() => gCheckAll(outCall, [outCall], "", [], [outInfo.ringing])) - .then(() => is(outCall.disconnectedReason, null)); -} - -function answer() { - return gRemoteAnswer(outCall) - .then(() => gCheckAll(outCall, [outCall], "", [], [outInfo.active])) - .then(() => is(outCall.disconnectedReason, null)); -} - -function hangUp() { - return gHangUp(outCall) - .then(() => gCheckAll(null, [], "", [], [])) - .then(() => is(outCall.disconnectedReason, "NormalCallClearing")); -} - -function remoteHangUp() { - return gRemoteHangUp(outCall) - .then(() => gCheckAll(null, [], "", [], [])) - .then(() => is(outCall.disconnectedReason, "NormalCallClearing")); -} - -function hold() { - return gHold(outCall) - .then(() => gCheckAll(null, [outCall], "", [], [outInfo.held])) - .then(() => is(outCall.disconnectedReason, null)); -} - -function resume() { - return gResume(outCall) - .then(() => gCheckAll(outCall, [outCall], "", [], [outInfo.active])) - .then(() => is(outCall.disconnectedReason, null)); -} - -// Test cases. - -function testOutgoingReject() { - log("= testOutgoingReject ="); - return outgoing() - .then(() => remoteHangUp()); -} - -function testOutgoingCancel() { - log("= testOutgoingCancel ="); - return outgoing() - .then(() => hangUp()); -} - -function testOutgoingAnswerHangUp() { - log("= testOutgoingAnswerHangUp ="); - return outgoing() - .then(() => answer()) - .then(() => hangUp()); -} - -function testOutgoingAnswerRemoteHangUp() { - log("= testOutgoingAnswerRemoteHangUp ="); - return outgoing() - .then(() => answer()) - .then(() => remoteHangUp()); -} - -function testOutgoingAnswerHoldHangUp() { - log("= testOutgoingAnswerHoldHangUp ="); - return outgoing() - .then(() => answer()) - .then(() => hold()) - .then(() => hangUp()); -} - -function testOutgoingAnswerHoldRemoteHangUp() { - log("= testOutgoingAnswerHoldRemoteHangUp ="); - return outgoing() - .then(() => answer()) - .then(() => hold()) - .then(() => remoteHangUp()); -} - -function testOutgoingAnswerHoldResumeHangUp() { - log("= testOutgoingAnswerHoldResumeHangUp ="); - return outgoing() - .then(() => answer()) - .then(() => hold()) - .then(() => resume()) - .then(() => hangUp()); -} - -function testOutgoingAnswerHoldResumeRemoteHangUp() { - log("= testOutgoingAnswerHoldResumeRemoteHangUp ="); - return outgoing() - .then(() => answer()) - .then(() => hold()) - .then(() => resume()) - .then(() => remoteHangUp()); -} - -startTest(function() { - Promise.resolve() - .then(() => testOutgoingReject()) - .then(() => testOutgoingCancel()) - .then(() => testOutgoingAnswerHangUp()) - .then(() => testOutgoingAnswerRemoteHangUp()) - .then(() => testOutgoingAnswerHoldHangUp()) - .then(() => testOutgoingAnswerHoldRemoteHangUp()) - .then(() => testOutgoingAnswerHoldResumeHangUp()) - .then(() => testOutgoingAnswerHoldResumeRemoteHangUp()) - - .catch(error => ok(false, "Promise reject: " + error)) - .then(finish); -}); From 901d8ca53a8d799814dd10d044fd291182d0f482 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 6 Oct 2015 00:59:53 -0700 Subject: [PATCH 08/60] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 4 ++-- b2g/config/emulator/sources.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 434079de15ff..aa844989d7e6 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -22,8 +22,8 @@ - - + + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 434079de15ff..aa844989d7e6 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -22,8 +22,8 @@ - - + + From fd52be5f45cb3accc47f67ea3d5fbf999477cff5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:08:14 +0200 Subject: [PATCH 09/60] Bug 1209085: Add 6-argument operator () to |UnpackPDUInitOp|, r=joliu --- ipc/hal/DaemonSocketPDUHelpers.h | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/ipc/hal/DaemonSocketPDUHelpers.h b/ipc/hal/DaemonSocketPDUHelpers.h index 1d7a0ae89407..3bd28c4f21df 100644 --- a/ipc/hal/DaemonSocketPDUHelpers.h +++ b/ipc/hal/DaemonSocketPDUHelpers.h @@ -1023,6 +1023,41 @@ public: WarnAboutTrailingData(); return NS_OK; } + + template + nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, + T5& aArg5, T6& aArg6) const + { + DaemonSocketPDU& pdu = GetPDU(); + + nsresult rv = UnpackPDU(pdu, aArg1); + if (NS_FAILED(rv)) { + return rv; + } + rv = UnpackPDU(pdu, aArg2); + if (NS_FAILED(rv)) { + return rv; + } + rv = UnpackPDU(pdu, aArg3); + if (NS_FAILED(rv)) { + return rv; + } + rv = UnpackPDU(pdu, aArg4); + if (NS_FAILED(rv)) { + return rv; + } + rv = UnpackPDU(pdu, aArg5); + if (NS_FAILED(rv)) { + return rv; + } + rv = UnpackPDU(pdu, aArg6); + if (NS_FAILED(rv)) { + return rv; + } + WarnAboutTrailingData(); + return NS_OK; + } }; } // namespace DaemonSocketPDUHelpers From 40d7b3a0034612a613086a0168b79a29c7adc606 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:08:14 +0200 Subject: [PATCH 10/60] Bug 1209085: Replace trivial init ops by |UnpackPDUInitOP| in Bluetooth A2DP backend, r=joliu --- .../BluetoothDaemonA2dpInterface.cpp | 104 +----------------- .../bluedroid/BluetoothDaemonA2dpInterface.h | 4 - 2 files changed, 3 insertions(+), 105 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp index d73b7344f741..c536bc31f9c9 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp @@ -170,129 +170,31 @@ public: } }; -// Init operator class for ConnectionStateNotification -class BluetoothDaemonA2dpModule::ConnectionStateInitOp final - : private PDUInitOp -{ -public: - ConnectionStateInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothA2dpConnectionState& aArg1, - BluetoothAddress& aArg2) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read state */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read address */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonA2dpModule::ConnectionStateNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { ConnectionStateNotification::Dispatch( &BluetoothA2dpNotificationHandler::ConnectionStateNotification, - ConnectionStateInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for AudioStateNotification -class BluetoothDaemonA2dpModule::AudioStateInitOp final - : private PDUInitOp -{ -public: - AudioStateInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothA2dpAudioState& aArg1, - BluetoothAddress& aArg2) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read state */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read address */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonA2dpModule::AudioStateNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { AudioStateNotification::Dispatch( &BluetoothA2dpNotificationHandler::AudioStateNotification, - AudioStateInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for AudioConfigNotification -class BluetoothDaemonA2dpModule::AudioConfigInitOp final - : private PDUInitOp -{ -public: - AudioConfigInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothAddress& aArg1, uint32_t aArg2, uint8_t aArg3) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read address */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read sample rate */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read channel count */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonA2dpModule::AudioConfigNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { AudioConfigNotification::Dispatch( &BluetoothA2dpNotificationHandler::AudioConfigNotification, - AudioConfigInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } void diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h index e1e1d648f739..2ddf1deaea1d 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h @@ -110,10 +110,6 @@ protected: const BluetoothAddress&, uint32_t, uint8_t> AudioConfigNotification; - class ConnectionStateInitOp; - class AudioStateInitOp; - class AudioConfigInitOp; - void ConnectionStateNtf(const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU); From ec9f010e9ff40d8ec06cc27cb6a1e16140a4f232 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:08:14 +0200 Subject: [PATCH 11/60] Bug 1209085: Replace trivial init ops by |UnpackPDUInitOp| in Bluetooth AVRCP backend, r=joliu --- .../BluetoothDaemonAvrcpInterface.cpp | 29 +------------------ .../bluedroid/BluetoothDaemonAvrcpInterface.h | 3 +- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp index 1a12e82d08ed..709fa44585d9 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp @@ -738,40 +738,13 @@ BluetoothDaemonAvrcpModule::VolumeChangeNtf( UnpackPDUInitOp(aPDU)); } -// Init operator class for PassthroughCmdNotification -class BluetoothDaemonAvrcpModule::PassthroughCmdInitOp final - : private PDUInitOp -{ -public: - PassthroughCmdInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (int& aArg1, int& aArg2) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, UnpackConversion(aArg2)); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonAvrcpModule::PassthroughCmdNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { PassthroughCmdNotification::Dispatch( &BluetoothAvrcpNotificationHandler::PassthroughCmdNotification, - PassthroughCmdInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } #endif diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h index 6327a75089f7..f06ebc0cc845 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h @@ -243,14 +243,13 @@ protected: VolumeChangeNotification; typedef mozilla::ipc::DaemonNotificationRunnable2< - NotificationHandlerWrapper, void, int, int> + NotificationHandlerWrapper, void, uint8_t, uint8_t, int, int> PassthroughCmdNotification; class GetElementAttrInitOp; class GetPlayerAppAttrsTextInitOp; class GetPlayerAppValueInitOp; class GetPlayerAppValuesTextInitOp; - class PassthroughCmdInitOp; class RemoteFeatureInitOp; void RemoteFeatureNtf(const DaemonSocketPDUHeader& aHeader, From 9c1afc7d890e0b6362bc9a7c0943b899ef46fa4e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:08:14 +0200 Subject: [PATCH 12/60] Bug 1209085: Replace simple init ops by |UnpackInitOp| in Bluetooth Core backend, r=joliu --- .../BluetoothDaemonCoreInterface.cpp | 169 +----------------- .../bluedroid/BluetoothDaemonCoreInterface.h | 4 - 2 files changed, 4 insertions(+), 169 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.cpp index 986ef448ed6c..a0402802e173 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.cpp @@ -945,201 +945,40 @@ BluetoothDaemonCoreModule::DiscoveryStateChangedNtf( UnpackPDUInitOp(aPDU)); } -// Init operator class for PinRequestNotification -class BluetoothDaemonCoreModule::PinRequestInitOp final - : private PDUInitOp -{ -public: - PinRequestInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothAddress& aArg1, BluetoothRemoteName& aArg2, - uint32_t& aArg3) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read remote address */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read remote name */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read CoD */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonCoreModule::PinRequestNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { PinRequestNotification::Dispatch( &BluetoothNotificationHandler::PinRequestNotification, - PinRequestInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for SspRequestNotification -class BluetoothDaemonCoreModule::SspRequestInitOp final - : private PDUInitOp -{ -public: - SspRequestInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothAddress& aArg1, BluetoothRemoteName& aArg2, - uint32_t& aArg3, BluetoothSspVariant& aArg4, - uint32_t& aArg5) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read remote address */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read remote name */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read CoD */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read pairing variant */ - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read passkey */ - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonCoreModule::SspRequestNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { SspRequestNotification::Dispatch( &BluetoothNotificationHandler::SspRequestNotification, - SspRequestInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for BondStateChangedNotification -class BluetoothDaemonCoreModule::BondStateChangedInitOp final - : private PDUInitOp -{ -public: - BondStateChangedInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothStatus& aArg1, BluetoothAddress& aArg2, - BluetoothBondState& aArg3) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read status */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read remote address */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read bond state */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonCoreModule::BondStateChangedNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { BondStateChangedNotification::Dispatch( &BluetoothNotificationHandler::BondStateChangedNotification, - BondStateChangedInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for AclStateChangedNotification -class BluetoothDaemonCoreModule::AclStateChangedInitOp final - : private PDUInitOp -{ -public: - AclStateChangedInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothStatus& aArg1, BluetoothAddress& aArg2, - BluetoothAclState& aArg3) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read status */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read remote address */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read ACL state */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonCoreModule::AclStateChangedNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { AclStateChangedNotification::Dispatch( &BluetoothNotificationHandler::AclStateChangedNotification, - AclStateChangedInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } // Init operator class for DutModeRecvNotification diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.h index aa24f889628e..f40506ca469f 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.h @@ -298,14 +298,10 @@ private: NotificationHandlerWrapper, void, BluetoothStatus, uint16_t> LeTestModeNotification; - class AclStateChangedInitOp; class AdapterPropertiesInitOp; - class BondStateChangedInitOp; class DeviceFoundInitOp; class DutModeRecvInitOp; - class PinRequestInitOp; class RemoteDevicePropertiesInitOp; - class SspRequestInitOp; void AdapterStateChangedNtf(const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU); From 9b0b498e50b633139fcb6dc955ca2d69c0790da7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:08:15 +0200 Subject: [PATCH 13/60] Bug 1209085: Replace simple init ops by |UnpackPDUInitOp| in Bluetooth GATT backend, r=joliu --- .../BluetoothDaemonGattInterface.cpp | 194 +----------------- .../bluedroid/BluetoothDaemonGattInterface.h | 6 +- 2 files changed, 6 insertions(+), 194 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp index 4cb694ade199..bccd546550cd 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp @@ -1568,56 +1568,13 @@ BluetoothDaemonGattModule::ClientScanResultNtf( ClientScanResultInitOp(aPDU)); } -// Init operator class for ClientConnect/DisconnectNotification -class BluetoothDaemonGattModule::ClientConnectDisconnectInitOp final - : private PDUInitOp -{ -public: - ClientConnectDisconnectInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (int& aArg1, - BluetoothGattStatus& aArg2, - int& aArg3, - BluetoothAddress& aArg4) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read connection ID */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - /* Read status */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - /* Read client interface */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - /* Read address */ - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonGattModule::ClientConnectNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { ClientConnectNotification::Dispatch( &BluetoothGattNotificationHandler::ConnectNotification, - ClientConnectDisconnectInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } void @@ -1626,7 +1583,7 @@ BluetoothDaemonGattModule::ClientDisconnectNtf( { ClientDisconnectNotification::Dispatch( &BluetoothGattNotificationHandler::DisconnectNotification, - ClientConnectDisconnectInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } void @@ -1737,56 +1694,13 @@ BluetoothDaemonGattModule::ClientExecuteWriteNtf( UnpackPDUInitOp(aPDU)); } -// Init operator class for ClientReadRemoteRssiNotification -class BluetoothDaemonGattModule::ClientReadRemoteRssiInitOp final - : private PDUInitOp -{ -public: - ClientReadRemoteRssiInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (int& aArg1, - BluetoothAddress& aArg2, - int& aArg3, - BluetoothGattStatus& aArg4) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read client interface */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - /* Read address */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - /* Read RSSI */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - /* Read status */ - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonGattModule::ClientReadRemoteRssiNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { ClientReadRemoteRssiNotification::Dispatch( &BluetoothGattNotificationHandler::ReadRemoteRssiNotification, - ClientReadRemoteRssiInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } void @@ -1922,68 +1836,13 @@ BluetoothDaemonGattModule::ServerServiceDeletedNtf( UnpackPDUInitOp(aPDU)); } -// Init operator class for ServerRequestReadNotification -class BluetoothDaemonGattModule::ServerRequestReadInitOp final - : private PDUInitOp -{ -public: - ServerRequestReadInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (int& aArg1, - int& aArg2, - BluetoothAddress& aArg3, - BluetoothAttributeHandle& aArg4, - int& aArg5, - bool& aArg6) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read connection ID */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - /* Read trans ID */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - /* Read address */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - /* Read attribute handle */ - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - /* Read offset */ - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - /* Read isLong */ - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonGattModule::ServerRequestReadNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { ServerRequestReadNotification::Dispatch( &BluetoothGattNotificationHandler::RequestReadNotification, - ServerRequestReadInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } // Init operator class for ServerRequestWriteNotification @@ -2069,56 +1928,13 @@ BluetoothDaemonGattModule::ServerRequestWriteNtf( ServerRequestWriteInitOp(aPDU)); } -// Init operator class for ServerRequestExecuteWriteNotification -class BluetoothDaemonGattModule::ServerRequestExecuteWriteInitOp final - : private PDUInitOp -{ -public: - ServerRequestExecuteWriteInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (int& aArg1, - int& aArg2, - BluetoothAddress& aArg3, - bool& aArg4) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read connection ID */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - /* Read trans ID */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - /* Read address */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - /* Read execute write */ - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonGattModule::ServerRequestExecuteWriteNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { ServerRequestExecuteWriteNotification::Dispatch( &BluetoothGattNotificationHandler::RequestExecuteWriteNotification, - ServerRequestExecuteWriteInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } void diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h index 7e106c2bb77d..fc7183fd8af6 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h @@ -681,14 +681,10 @@ protected: BluetoothGattStatus, int> ServerResponseConfirmationNotification; - class ClientScanResultInitOp; - class ClientConnectDisconnectInitOp; - class ClientReadRemoteRssiInitOp; class ClientGetDeviceTypeInitOp; + class ClientScanResultInitOp; class ServerConnectionInitOp; - class ServerRequestReadInitOp; class ServerRequestWriteInitOp; - class ServerRequestExecuteWriteInitOp; void ClientRegisterNtf(const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU); From 37726b2ea920fb654b5c6ec4d4521676af51ae49 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:08:15 +0200 Subject: [PATCH 14/60] Bug 1209085: Replace simple init ops by |UnpackPDUInitOp| in Blutooth HFP backend, r=joliu --- .../BluetoothDaemonHandsfreeInterface.cpp | 66 +------------------ .../BluetoothDaemonHandsfreeInterface.h | 2 - 2 files changed, 2 insertions(+), 66 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp index 05e3ccf54b1c..1fafbce9582b 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp @@ -777,44 +777,13 @@ BluetoothDaemonHandsfreeModule::ConnectionStateNtf( ConnectionStateInitOp(aPDU)); } -// Init operator class for AudioStateNotification -class BluetoothDaemonHandsfreeModule::AudioStateInitOp final - : private PDUInitOp -{ -public: - AudioStateInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothHandsfreeAudioState& aArg1, - BluetoothAddress& aArg2) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read state */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read address */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::AudioStateNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { AudioStateNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::AudioStateNotification, - AudioStateInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } // Init operator class for VoiceRecognitionNotification @@ -1381,44 +1350,13 @@ BluetoothDaemonHandsfreeModule::KeyPressedNtf( KeyPressedInitOp(aPDU)); } -// Init operator class for WbsNotification -class BluetoothDaemonHandsfreeModule::WbsInitOp final - : private PDUInitOp -{ -public: - WbsInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothHandsfreeWbsConfig& aArg1, BluetoothAddress& aArg2) const - { - DaemonSocketPDU& pdu = GetPDU(); - - /* Read state */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read address */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::WbsNtf( const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU) { WbsNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::WbsNotification, - WbsInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } void diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h index 83f9d32e2fc9..fe8345611fef 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h @@ -314,7 +314,6 @@ protected: WbsNotification; class ConnectionStateInitOp; - class AudioStateInitOp; class VoiceRecognitionInitOp; class AnswerCallInitOp; class HangupCallInitOp; @@ -330,7 +329,6 @@ protected: class VolumeInitOp; class UnknownAtInitOp; class KeyPressedInitOp; - class WbsInitOp; void ConnectionStateNtf(const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU); From 613fc1bb77bacaa9f4d37acec352244d2c0b58b5 Mon Sep 17 00:00:00 2001 From: Ben Hsu Date: Tue, 15 Sep 2015 02:03:00 +0200 Subject: [PATCH 15/60] Bug 1204817 - Delete the child property of a parent call only when the parent call exists. r=btseng --- dom/telephony/gonk/TelephonyService.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dom/telephony/gonk/TelephonyService.js b/dom/telephony/gonk/TelephonyService.js index d9f78b517f6b..06c24f7174fa 100644 --- a/dom/telephony/gonk/TelephonyService.js +++ b/dom/telephony/gonk/TelephonyService.js @@ -2211,10 +2211,9 @@ TelephonyService.prototype = { aFailCause = RIL.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING) { if (DEBUG) debug("_disconnectCalls: " + JSON.stringify(aCalls)); - // Child cannot live without parent. Let's find all the calls that need to - // be disconnected. + // In addition to the disconnected call itself, its decedent calls should be + // treated as disconnected calls as well. let disconnectedCalls = aCalls.slice(); - for (let call in aCalls) { while (call.childId) { call = this._currentCalls[aClientId][call.childId]; @@ -2231,8 +2230,8 @@ TelephonyService.prototype = { call.state = nsITelephonyService.CALL_STATE_DISCONNECTED; call.disconnectedReason = aFailCause; - if (call.parentId) { - let parentCall = this._currentCalls[aClientId][call.parentId]; + let parentCall = this._currentCalls[aClientId][call.parentId]; + if (parentCall) { delete parentCall.childId; } From 2b511b9bdf688485f11c255603786e2f75e90162 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 28 Sep 2015 09:49:00 +0200 Subject: [PATCH 16/60] Bug 1195357 - make stringifyProperty escape text for CSS comment; r=pbrosset --- devtools/client/styleinspector/rule-view.js | 3 +- .../test/browser_ruleview_copy_styles.js | 31 +++++++++++++++++-- .../styleinspector/test/doc_copystyles.css | 1 + 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/devtools/client/styleinspector/rule-view.js b/devtools/client/styleinspector/rule-view.js index f0740eed767c..5253d0228229 100644 --- a/devtools/client/styleinspector/rule-view.js +++ b/devtools/client/styleinspector/rule-view.js @@ -26,6 +26,7 @@ const { throttle } = require("devtools/client/styleinspector/utils"); const { + escapeCSSComment, parseDeclarations, parseSingleValue, parsePseudoClassesAndAttributes, @@ -1117,7 +1118,7 @@ TextProperty.prototype = { // Comment out property declarations that are not enabled if (!this.enabled) { - declaration = "/* " + declaration + " */"; + declaration = "/* " + escapeCSSComment(declaration) + " */"; } return declaration; diff --git a/devtools/client/styleinspector/test/browser_ruleview_copy_styles.js b/devtools/client/styleinspector/test/browser_ruleview_copy_styles.js index cac459e4bc30..f081d26ce52d 100644 --- a/devtools/client/styleinspector/test/browser_ruleview_copy_styles.js +++ b/devtools/client/styleinspector/test/browser_ruleview_copy_styles.js @@ -103,6 +103,7 @@ add_task(function*() { "\tbackground-color: #00F;[\\r\\n]+" + "\tfont-size: 12px;[\\r\\n]+" + "\tborder-color: #00F !important;[\\r\\n]+" + + "\t--var: \"\\*/\";[\\r\\n]+" + "}", hidden: { copyLocation: true, @@ -144,7 +145,7 @@ add_task(function*() { }, { setup: function*() { - yield disableProperty(view); + yield disableProperty(view, 0); }, desc: "Test Copy Rule with Disabled Property", node: ruleEditor.rule.textProps[2].editor.nameSpan, @@ -154,6 +155,30 @@ add_task(function*() { "\tbackground-color: #00F;[\\r\\n]+" + "\tfont-size: 12px;[\\r\\n]+" + "\tborder-color: #00F !important;[\\r\\n]+" + + "\t--var: \"\\*/\";[\\r\\n]+" + + "}", + hidden: { + copyLocation: true, + copyPropertyDeclaration: false, + copyPropertyName: false, + copyPropertyValue: true, + copySelector: true, + copyRule: false + } + }, + { + setup: function*() { + yield disableProperty(view, 4); + }, + desc: "Test Copy Rule with Disabled Property with Comment", + node: ruleEditor.rule.textProps[2].editor.nameSpan, + menuItem: contextmenu.menuitemCopyRule, + expectedPattern: "#testid {[\\r\\n]+" + + "\t\/\\* color: #F00; \\*\/[\\r\\n]+" + + "\tbackground-color: #00F;[\\r\\n]+" + + "\tfont-size: 12px;[\\r\\n]+" + + "\tborder-color: #00F !important;[\\r\\n]+" + + "\t/\\* --var: \"\\*\\\\\/\"; \\*\/[\\r\\n]+" + "}", hidden: { copyLocation: true, @@ -241,9 +266,9 @@ function* checkCopyStyle(view, node, menuItem, expectedPattern, hidden) { view._contextmenu._menupopup.hidePopup(); } -function* disableProperty(view) { +function* disableProperty(view, index) { let ruleEditor = getRuleViewRuleEditor(view, 1); - let propEditor = ruleEditor.rule.textProps[0].editor; + let propEditor = ruleEditor.rule.textProps[index].editor; info("Disabling a property"); propEditor.enable.click(); diff --git a/devtools/client/styleinspector/test/doc_copystyles.css b/devtools/client/styleinspector/test/doc_copystyles.css index 7494c11a6fce..83f0c87b1262 100644 --- a/devtools/client/styleinspector/test/doc_copystyles.css +++ b/devtools/client/styleinspector/test/doc_copystyles.css @@ -7,4 +7,5 @@ html, body, #testid { background-color: #00F; font-size: 12px; border-color: #00F !important; + --var: "*/"; } From c43954f28dfe847ce6b4b357c9d0e6e833c77e20 Mon Sep 17 00:00:00 2001 From: Edouard Oger Date: Sun, 4 Oct 2015 11:19:00 +0200 Subject: [PATCH 17/60] Bug 1210947 - Center buttons text in sync preferences. r=markh --- browser/themes/shared/incontentprefs/preferences.inc.css | 1 + 1 file changed, 1 insertion(+) diff --git a/browser/themes/shared/incontentprefs/preferences.inc.css b/browser/themes/shared/incontentprefs/preferences.inc.css index de70f654676e..ac431b28fac5 100644 --- a/browser/themes/shared/incontentprefs/preferences.inc.css +++ b/browser/themes/shared/incontentprefs/preferences.inc.css @@ -589,6 +589,7 @@ description > html|a { } .fxaAccountBoxButtons > button { + text-align: center; padding-left: 11px; padding-right: 11px; margin: 0; From 0bb22245ffdad0af809752c4cd4035e04dad9159 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Mon, 5 Oct 2015 08:01:00 +0200 Subject: [PATCH 18/60] Bug 1211221 - Add a unit to the --tab-toolbar-navbar-overlap CSS varialbe to please the calc() parser. r=Gijs --- browser/themes/windows/browser.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css index 5337061cd798..cea8a568d71a 100644 --- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -2013,7 +2013,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action- } :root { - --tab-toolbar-navbar-overlap: 0; + --tab-toolbar-navbar-overlap: 0px; } #nav-bar { From 7c2d9ade653f4f40f5ac356bb3c0b3aa21331f3e Mon Sep 17 00:00:00 2001 From: Richard Marti Date: Sat, 3 Oct 2015 22:12:35 +0200 Subject: [PATCH 19/60] Bug 1211250 - Backout bug 1206469 after landing of bug 1194480. r=gijs --- browser/themes/windows/customizableui/panelUIOverlay.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/browser/themes/windows/customizableui/panelUIOverlay.css b/browser/themes/windows/customizableui/panelUIOverlay.css index 2f5c86c2bfaf..a2c59cb88990 100644 --- a/browser/themes/windows/customizableui/panelUIOverlay.css +++ b/browser/themes/windows/customizableui/panelUIOverlay.css @@ -223,9 +223,7 @@ menu.subviewbutton > .menu-right:-moz-locale-dir(rtl) { } #BMB_bookmarksPopup menupopup[placespopup=true] > hbox { - /* After fixing of bug 1194480 the box-shadow can be removed again */ - /* box-shadow: none; */ - box-shadow: 0 0 4px rgba(0,0,0,0.02); + box-shadow: none; background: -moz-field; border: 1px solid ThreeDShadow; } From f584a74473e081451ac9c5aad0969425caf2983e Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Tue, 6 Oct 2015 10:35:08 +0200 Subject: [PATCH 20/60] Bug 1171213 - Allocator: Suppress deprecation notification for Context.MODE_MULTI_PROCESS. r=mfinkle --HG-- extra : commitid : 5asluPIg1vv extra : rebase_source : 37aab7a7a92531b3abaaf49b1ec8a55043770f79 --- mobile/android/base/webapp/Allocator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mobile/android/base/webapp/Allocator.java b/mobile/android/base/webapp/Allocator.java index 9f9786db27dd..e7a18bdef75c 100644 --- a/mobile/android/base/webapp/Allocator.java +++ b/mobile/android/base/webapp/Allocator.java @@ -11,7 +11,6 @@ import org.mozilla.gecko.GeckoAppShell; import android.content.Context; import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; import android.util.Log; public class Allocator { @@ -46,6 +45,8 @@ public class Allocator { SharedPreferences mPrefs; + @SuppressWarnings("deprecation") // Suppressing deprecation notification for Context.MODE_MULTI_PROCESS until we + // reach a timeline for removal of the whole feature. (Bug 1171213) protected Allocator(Context context) { mPrefs = context.getSharedPreferences("webapps", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS); } From 03a2ea5f2ec8395b34d31ccd12f0cb2c793a201a Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 6 Oct 2015 22:17:41 +1100 Subject: [PATCH 21/60] Bug 1161565 - Give titlebar proper appearance on OS X Yosemite and revmoe special case of double click behavior on unified tabbar on OS X. r=gijs --HG-- extra : source : ab5152f6824840563f677260e56672964c7b0a7e --- browser/base/content/tabbrowser.xml | 12 +++++------- browser/themes/osx/browser.css | 6 ------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index e2e0b88254b2..7eb4300b733d 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -5355,13 +5355,11 @@ ]]> #titlebar { - -moz-appearance: -moz-mac-vibrancy-light; - } -} - #main-window:not([tabsintitlebar]) > #titlebar { height: 22px; /* The native titlebar on OS X is 22px tall. */ } From 3656c863e9a505e5abb8c28434ab08e90e0422f1 Mon Sep 17 00:00:00 2001 From: Mark Finkle Date: Tue, 6 Oct 2015 08:11:52 -0400 Subject: [PATCH 22/60] Bug 1026669 - Limit SSDP polling to when Firefox is in the foreground r=margaret --- mobile/android/chrome/content/CastingApps.js | 28 +++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/mobile/android/chrome/content/CastingApps.js b/mobile/android/chrome/content/CastingApps.js index 341628290492..4d8177823e36 100644 --- a/mobile/android/chrome/content/CastingApps.js +++ b/mobile/android/chrome/content/CastingApps.js @@ -65,6 +65,7 @@ var CastingApps = { mirrorStopMenuId: -1, _blocked: null, _bound: null, + _interval: 120 * 1000, // 120 seconds init: function ca_init() { if (!this.isCastingEnabled()) { @@ -78,8 +79,8 @@ var CastingApps = { mediaPlayerDevice.init(); SimpleServiceDiscovery.registerDevice(mediaPlayerDevice); - // Search for devices continuously every 120 seconds - SimpleServiceDiscovery.search(120 * 1000); + // Search for devices continuously + SimpleServiceDiscovery.search(this._interval); this._castMenuId = NativeWindow.contextmenus.add( Strings.browser.GetStringFromName("contextmenu.sendToDevice"), @@ -93,6 +94,8 @@ var CastingApps = { Services.obs.addObserver(this, "Casting:Mirror", false); Services.obs.addObserver(this, "ssdp-service-found", false); Services.obs.addObserver(this, "ssdp-service-lost", false); + Services.obs.addObserver(this, "application-background", false); + Services.obs.addObserver(this, "application-foreground", false); BrowserApp.deck.addEventListener("TabSelect", this, true); BrowserApp.deck.addEventListener("pageshow", this, true); @@ -195,15 +198,20 @@ var CastingApps = { } break; case "ssdp-service-found": - { - this.serviceAdded(SimpleServiceDiscovery.findServiceForID(aData)); - break; - } + this.serviceAdded(SimpleServiceDiscovery.findServiceForID(aData)); + break; case "ssdp-service-lost": - { - this.serviceLost(SimpleServiceDiscovery.findServiceForID(aData)); - break; - } + this.serviceLost(SimpleServiceDiscovery.findServiceForID(aData)); + break; + case "application-background": + // Turn off polling while in the background + this._interval = SimpleServiceDiscovery.search(0); + SimpleServiceDiscovery.stopSearch(); + break; + case "application-foreground": + // Turn polling on when app comes back to foreground + SimpleServiceDiscovery.search(this._interval); + break; } }, From 1f12033291266d78cf1f18d3703c68ce9438533a Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Thu, 1 Oct 2015 13:42:44 -0400 Subject: [PATCH 23/60] Bug 1110511 - Use the browser permanentKey to map to childIDs in TabCrashReporter. r=felipe --HG-- extra : commitid : 6Z2a3BxiuJ6 extra : source : 0e055b648e1003d29b243e036aef43565f2e9874 --- browser/modules/ContentCrashReporters.jsm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/browser/modules/ContentCrashReporters.jsm b/browser/modules/ContentCrashReporters.jsm index 34a1bd75b74f..badefa513031 100644 --- a/browser/modules/ContentCrashReporters.jsm +++ b/browser/modules/ContentCrashReporters.jsm @@ -47,13 +47,13 @@ this.TabCrashReporter = { if (!browser) return; - this.browserMap.set(browser, aSubject.childID); + this.browserMap.set(browser.permanentKey, aSubject.childID); break; } }, submitCrashReport: function (aBrowser) { - let childID = this.browserMap.get(aBrowser); + let childID = this.browserMap.get(aBrowser.permanentKey); let dumpID = this.childMap.get(childID); if (!dumpID) return @@ -79,8 +79,8 @@ this.TabCrashReporter = { if (!doc.documentURI.startsWith("about:tabcrashed")) continue; - if (this.browserMap.get(browser) == childID) { - this.browserMap.delete(browser); + if (this.browserMap.get(browser.permanentKey) == childID) { + this.browserMap.delete(browser.permanentKey); browser.contentDocument.documentElement.classList.remove("crashDumpAvailable"); browser.contentDocument.documentElement.classList.add("crashDumpSubmitted"); } @@ -97,7 +97,7 @@ this.TabCrashReporter = { if (!this.childMap) return; - let dumpID = this.childMap.get(this.browserMap.get(aBrowser)); + let dumpID = this.childMap.get(this.browserMap.get(aBrowser.permanentKey)); if (!dumpID) return; From d46d8fbfbd87de054755cd8acc6e84a5a6fdaca1 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Mon, 28 Sep 2015 18:39:39 -0400 Subject: [PATCH 24/60] Bug 1110511 - Allow TabCrashReporter to pass extraExtraKeyVals. r=felipe --HG-- extra : commitid : 69Ly6A88hOv extra : source : 219d86f78b6be95ffbac8d005c428cd04db11150 --- browser/modules/ContentCrashReporters.jsm | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/browser/modules/ContentCrashReporters.jsm b/browser/modules/ContentCrashReporters.jsm index badefa513031..562be1f3aca0 100644 --- a/browser/modules/ContentCrashReporters.jsm +++ b/browser/modules/ContentCrashReporters.jsm @@ -52,16 +52,23 @@ this.TabCrashReporter = { } }, - submitCrashReport: function (aBrowser) { + submitCrashReport: function (aBrowser, aFormData) { let childID = this.browserMap.get(aBrowser.permanentKey); let dumpID = this.childMap.get(childID); if (!dumpID) return - if (CrashSubmit.submit(dumpID, { recordSubmission: true })) { - this.childMap.set(childID, null); // Avoid resubmission. - this.removeSubmitCheckboxesForSameCrash(childID); - } + CrashSubmit.submit(dumpID, { + recordSubmission: true, + extraExtraKeyVals: { + Comments: aFormData.comments, + Email: aFormData.email, + URL: aFormData.URL, + }, + }).then(null, Cu.reportError); + + this.childMap.set(childID, null); // Avoid resubmission. + this.removeSubmitCheckboxesForSameCrash(childID); }, removeSubmitCheckboxesForSameCrash: function(childID) { From 010f344a617711e7786f919dbb3748873857df80 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Thu, 1 Oct 2015 14:53:09 -0400 Subject: [PATCH 25/60] Bug 1110511 - Fix erroneous references to html|textbox in in-content's common.css. r=ntim --HG-- extra : commitid : AzEj426e4WA extra : source : c7b983f655685051c0ed691ca1dfbdd47a3e964a --- toolkit/themes/shared/in-content/common.inc.css | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css index c3c77d8995bd..1673aecb439b 100644 --- a/toolkit/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -406,7 +406,7 @@ xul|button[type="menu"] > xul|menupopup xul|menuseparator { /* textboxes */ -*|textbox { +xul|textbox { -moz-appearance: none; height: 30px; color: var(--in-content-text-color); @@ -422,12 +422,14 @@ xul|button[type="menu"] > xul|menupopup xul|menuseparator { background-color: var(--in-content-box-background); } -html|textbox:focus, +html|input[type="text"]:focus, +html|textarea:focus, xul|textbox[focused] { border-color: var(--in-content-border-focus); } -html|textbox:disabled, +html|input[type="text"]:disabled, +html|textarea:disabled, xul|textbox[disabled="true"] { opacity: 0.5; } From dc52923a833e81301cf3118277eaea1baad2e1db Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 30 Sep 2015 17:50:48 -0400 Subject: [PATCH 26/60] Bug 1110511 - Add comment and email input to about:tabcrashed. r=felipe,ntim Original patch by Ursula Sarracini --HG-- extra : commitid : 1lruBAoE7jC extra : source : 8e20cd68ca78366976495c9a7f003f0f120c1166 --- browser/app/profile/firefox.js | 6 ++ browser/base/content/aboutTabCrashed.js | 68 ++++++++++++++++--- browser/base/content/aboutTabCrashed.xhtml | 16 ++++- browser/base/content/browser.js | 10 ++- .../en-US/chrome/browser/aboutTabCrashed.dtd | 5 ++ browser/modules/ContentCrashReporters.jsm | 61 ++++++++++++++++- browser/themes/shared/aboutTabCrashed.css | 31 +++++++++ .../themes/shared/in-content/common.inc.css | 19 ++++-- 8 files changed, 200 insertions(+), 16 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index c0e188586d90..052a23c8f02c 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1882,6 +1882,12 @@ pref("browser.tabs.remote.autostart.1", false); pref("browser.tabs.remote.autostart.2", true); #endif +// For the about:tabcrashed page +pref("browser.tabs.crashReporting.sendReport", true); +pref("browser.tabs.crashReporting.includeURL", false); +pref("browser.tabs.crashReporting.emailMe", false); +pref("browser.tabs.crashReporting.email", ""); + #ifdef NIGHTLY_BUILD #ifndef MOZ_MULET pref("layers.async-pan-zoom.enabled", true); diff --git a/browser/base/content/aboutTabCrashed.js b/browser/base/content/aboutTabCrashed.js index a0abedc0e58f..5ff0071a46e2 100644 --- a/browser/base/content/aboutTabCrashed.js +++ b/browser/base/content/aboutTabCrashed.js @@ -3,27 +3,66 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ function parseQueryString() { - let url = document.documentURI; - let queryString = url.replace(/^about:tabcrashed?e=tabcrashed/, ""); + let URL = document.documentURI; + let queryString = URL.replace(/^about:tabcrashed?e=tabcrashed/, ""); let titleMatch = queryString.match(/d=([^&]*)/); - return titleMatch && titleMatch[1] ? decodeURIComponent(titleMatch[1]) : ""; + let URLMatch = queryString.match(/u=([^&]*)/); + return { + title: titleMatch && titleMatch[1] ? decodeURIComponent(titleMatch[1]) : "", + URL: URLMatch && URLMatch[1] ? decodeURIComponent(URLMatch[1]) : "", + }; } -document.title = parseQueryString(); +function displayUI() { + if (!hasReport()) { + return; + } -function shouldSendReport() { - if (!document.documentElement.classList.contains("crashDumpAvailable")) - return false; - return document.getElementById("sendReport").checked; + let sendCrashReport = document.getElementById("sendReport").checked; + let container = document.getElementById("crash-reporter-container"); + container.hidden = !sendCrashReport; +} + +function hasReport() { + return document.documentElement.classList.contains("crashDumpAvailable"); } function sendEvent(message) { + let comments = ""; + let email = ""; + let URL = ""; + let sendCrashReport = false; + let emailMe = false; + let includeURL = false; + + if (hasReport()) { + sendCrashReport = document.getElementById("sendReport").checked; + if (sendCrashReport) { + comments = document.getElementById("comments").value.trim(); + + includeURL = document.getElementById("includeURL").checked; + if (includeURL) { + URL = parseQueryString().URL.trim(); + } + + emailMe = document.getElementById("emailMe").checked; + if (emailMe) { + email = document.getElementById("email").value.trim(); + } + } + } + let event = new CustomEvent("AboutTabCrashedMessage", { bubbles: true, detail: { message, - sendCrashReport: shouldSendReport(), + sendCrashReport, + comments, + email, + emailMe, + includeURL, + URL, }, }); @@ -42,6 +81,17 @@ function restoreAll() { sendEvent("restoreAll"); } +document.title = parseQueryString().title; + // Error pages are loaded as LOAD_BACKGROUND, so they don't get load events. var event = new CustomEvent("AboutTabCrashedLoad", {bubbles:true}); document.dispatchEvent(event); + +addEventListener("DOMContentLoaded", function() { + let sendReport = document.getElementById("sendReport"); + sendReport.addEventListener("click", function() { + displayUI(); + }); + + displayUI(); +}); diff --git a/browser/base/content/aboutTabCrashed.xhtml b/browser/base/content/aboutTabCrashed.xhtml index ec1f37161bf1..9de02cc21029 100644 --- a/browser/base/content/aboutTabCrashed.xhtml +++ b/browser/base/content/aboutTabCrashed.xhtml @@ -37,8 +37,22 @@

&tabCrashed.message;

- + +

&tabCrashed.reportSent;

diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index ed10547395f3..c3e933b338e8 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1166,7 +1166,15 @@ var gBrowserInit = { let browser = gBrowser.getBrowserForDocument(ownerDoc); #ifdef MOZ_CRASHREPORTER if (event.detail.sendCrashReport) { - TabCrashReporter.submitCrashReport(browser); + TabCrashReporter.submitCrashReport(browser, { + comments: event.detail.comments, + email: event.detail.email, + emailMe: event.detail.emailMe, + includeURL: event.detail.includeURL, + URL: event.detail.URL, + }); + } else { + TabCrashReporter.dontSubmitCrashReport(); } #endif diff --git a/browser/locales/en-US/chrome/browser/aboutTabCrashed.dtd b/browser/locales/en-US/chrome/browser/aboutTabCrashed.dtd index 609e001989e4..eac62d7211f9 100644 --- a/browser/locales/en-US/chrome/browser/aboutTabCrashed.dtd +++ b/browser/locales/en-US/chrome/browser/aboutTabCrashed.dtd @@ -5,6 +5,11 @@ + + + + + diff --git a/browser/modules/ContentCrashReporters.jsm b/browser/modules/ContentCrashReporters.jsm index 562be1f3aca0..7c43d9fbb201 100644 --- a/browser/modules/ContentCrashReporters.jsm +++ b/browser/modules/ContentCrashReporters.jsm @@ -17,6 +17,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit", "resource://gre/modules/CrashSubmit.jsm"); this.TabCrashReporter = { + get prefs() { + delete this.prefs; + return this.prefs = Services.prefs.getBranch("browser.tabs.crashReporting."); + }, + init: function () { if (this.initialized) return; @@ -52,6 +57,31 @@ this.TabCrashReporter = { } }, + /** + * Submits a crash report from about:tabcrashed + * + * @param aBrowser + * The that the report was sent from. + * @param aFormData + * An Object with the following properties: + * + * includeURL (bool): + * Whether to include the URL that the user was on + * in the crashed tab before the crash occurred. + * URL (String) + * The URL that the user was on in the crashed tab + * before the crash occurred. + * emailMe (bool): + * Whether or not to include the user's email address + * in the crash report. + * email (String): + * The email address of the user. + * comments (String): + * Any additional comments from the user. + * + * Note that it is expected that all properties are set, + * even if they are empty. + */ submitCrashReport: function (aBrowser, aFormData) { let childID = this.browserMap.get(aBrowser.permanentKey); let dumpID = this.childMap.get(childID); @@ -67,10 +97,23 @@ this.TabCrashReporter = { }, }).then(null, Cu.reportError); + this.prefs.setBoolPref("sendReport", true); + this.prefs.setBoolPref("includeURL", aFormData.includeURL); + this.prefs.setBoolPref("emailMe", aFormData.emailMe); + if (aFormData.emailMe) { + this.prefs.setCharPref("email", aFormData.email); + } else { + this.prefs.setCharPref("email", ""); + } + this.childMap.set(childID, null); // Avoid resubmission. this.removeSubmitCheckboxesForSameCrash(childID); }, + dontSubmitCrashReport: function() { + this.prefs.setBoolPref("sendReport", false); + }, + removeSubmitCheckboxesForSameCrash: function(childID) { let enumerator = Services.wm.getEnumerator("navigator:browser"); while (enumerator.hasMoreElements()) { @@ -108,7 +151,23 @@ this.TabCrashReporter = { if (!dumpID) return; - aBrowser.contentDocument.documentElement.classList.add("crashDumpAvailable"); + let doc = aBrowser.contentDocument; + + doc.documentElement.classList.add("crashDumpAvailable"); + + let sendReport = this.prefs.getBoolPref("sendReport"); + doc.getElementById("sendReport").checked = sendReport; + + let includeURL = this.prefs.getBoolPref("includeURL"); + doc.getElementById("includeURL").checked = includeURL; + + let emailMe = this.prefs.getBoolPref("emailMe"); + doc.getElementById("emailMe").checked = emailMe; + + if (emailMe) { + let email = this.prefs.getCharPref("email", ""); + doc.getElementById("email").value = email; + } }, hideRestoreAllButton: function (aBrowser) { diff --git a/browser/themes/shared/aboutTabCrashed.css b/browser/themes/shared/aboutTabCrashed.css index 2ef767eb8b24..e42922ac95d6 100644 --- a/browser/themes/shared/aboutTabCrashed.css +++ b/browser/themes/shared/aboutTabCrashed.css @@ -9,3 +9,34 @@ #reportSent { font-weight: bold; } + +#crash-reporter-container { + width: 80%; + background-color: var(--in-content-box-background-hover); + margin: 24px 0; + padding: 14px; + border: 1px solid var(--in-content-box-border-color); + border-radius: 2px; +} + +#crash-reporter-title { + font-weight: bold; + margin: 0 0 14px 0; +} + +input[type="text"], +textarea { + width: 100%; + box-sizing: border-box; + resize: none; +} + +#options { + list-style: none; + margin-inline-start: 0; +} + +input[type="text"], +#options > li { + margin: 14px 0 0 0; +} diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css index 1673aecb439b..1b19a93bc217 100644 --- a/toolkit/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -406,13 +406,11 @@ xul|button[type="menu"] > xul|menupopup xul|menuseparator { /* textboxes */ +html|input[type="text"], +html|textarea, xul|textbox { -moz-appearance: none; - height: 30px; color: var(--in-content-text-color); - line-height: 20px; - padding-right: 10px; - padding-left: 10px; border: 1px solid var(--in-content-box-border-color); -moz-border-top-colors: none !important; -moz-border-right-colors: none !important; @@ -422,6 +420,19 @@ xul|textbox { background-color: var(--in-content-box-background); } +xul|textbox { + min-height: 30px; + padding-right: 10px; + padding-left: 10px; +} + +html|input[type="text"], +html|textarea { + font-family: inherit; + font-size: inherit; + padding: 5px 10px; +} + html|input[type="text"]:focus, html|textarea:focus, xul|textbox[focused] { From f29c98bfde1422f55cb2427813115d0763c68d5c Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Tue, 29 Sep 2015 16:44:50 -0400 Subject: [PATCH 27/60] Bug 1110511 - Move tab-crashing test helper function to BrowserTestUtils.jsm r=felipe --HG-- extra : commitid : 4ACRUHc4rlx extra : source : 0eb0dda094b30354a84991e430a0e49320fde52b extra : amend_source : 32bd586ee11bb38ddb733ced6d86179b051b7f96 --- .../test/browser_async_flushes.js | 2 +- .../sessionstore/test/browser_crashedTabs.js | 18 +-- browser/components/sessionstore/test/head.js | 106 ------------- .../BrowserTestUtils/BrowserTestUtils.jsm | 145 +++++++++++++++++- .../browser/browser_content_url_annotation.js | 68 +------- 5 files changed, 155 insertions(+), 184 deletions(-) diff --git a/browser/components/sessionstore/test/browser_async_flushes.js b/browser/components/sessionstore/test/browser_async_flushes.js index f5496e9e60e3..fe6e5b639ffd 100644 --- a/browser/components/sessionstore/test/browser_async_flushes.js +++ b/browser/components/sessionstore/test/browser_async_flushes.js @@ -69,7 +69,7 @@ add_task(function* test_crash() { // the content process. The "crash" message makes it first so that we don't // get a chance to process the flush. The TabStateFlusher however should be // notified so that the flush still completes. - let promise1 = crashBrowser(browser); + let promise1 = BrowserTestUtils.crashBrowser(browser); let promise2 = TabStateFlusher.flush(browser); yield Promise.all([promise1, promise2]); diff --git a/browser/components/sessionstore/test/browser_crashedTabs.js b/browser/components/sessionstore/test/browser_crashedTabs.js index 71eca9e0baa4..72df2d2a6c45 100644 --- a/browser/components/sessionstore/test/browser_crashedTabs.js +++ b/browser/components/sessionstore/test/browser_crashedTabs.js @@ -117,7 +117,7 @@ add_task(function test_crash_page_not_in_history() { yield TabStateFlusher.flush(browser); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); // Check the tab state and make sure the tab crashed page isn't // mentioned. @@ -146,7 +146,7 @@ add_task(function test_revived_history_from_remote() { yield TabStateFlusher.flush(browser); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); // Browse to a new site that will cause the browser to // become remote again. @@ -185,7 +185,7 @@ add_task(function test_revived_history_from_non_remote() { yield TabStateFlusher.flush(browser); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); // Browse to a new site that will not cause the browser to // become remote again. @@ -235,7 +235,7 @@ add_task(function test_revive_tab_from_session_store() { yield TabStateFlusher.flush(browser); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); is(newTab2.getAttribute("crashed"), "true", "Second tab should be crashed too."); // Use SessionStore to revive the tab @@ -286,7 +286,7 @@ add_task(function test_revive_all_tabs_from_session_store() { yield TabStateFlusher.flush(browser2); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); is(newTab2.getAttribute("crashed"), "true", "Second tab should be crashed too."); // Use SessionStore to revive all the tabs @@ -331,7 +331,7 @@ add_task(function test_close_tab_after_crash() { yield TabStateFlusher.flush(browser); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); let promise = promiseEvent(gBrowser.tabContainer, "TabClose"); @@ -359,7 +359,7 @@ add_task(function* test_hide_restore_all_button() { yield TabStateFlusher.flush(browser); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); let doc = browser.contentDocument; let restoreAllButton = doc.getElementById("restoreAll"); @@ -375,7 +375,7 @@ add_task(function* test_hide_restore_all_button() { yield promiseBrowserLoaded(browser); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); doc = browser.contentDocument; restoreAllButton = doc.getElementById("restoreAll"); @@ -405,7 +405,7 @@ add_task(function* test_aboutcrashedtabzoom() { yield TabStateFlusher.flush(browser); // Crash the tab - yield crashBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); ok(ZoomManager.getZoomForBrowser(browser) === 1, "zoom should have reset on crash"); diff --git a/browser/components/sessionstore/test/head.js b/browser/components/sessionstore/test/head.js index da4c0328ee0c..af326cc7c704 100644 --- a/browser/components/sessionstore/test/head.js +++ b/browser/components/sessionstore/test/head.js @@ -538,112 +538,6 @@ function promiseRemoveTab(tab) { return BrowserTestUtils.removeTab(tab); } -/** - * Returns a Promise that resolves once a remote has experienced - * a crash. Also does the job of cleaning up the minidump of the crash. - * - * @param browser - * The that will crash - * @return Promise - */ -function crashBrowser(browser) { - /** - * Returns the directory where crash dumps are stored. - * - * @return nsIFile - */ - function getMinidumpDirectory() { - let dir = Services.dirsvc.get('ProfD', Ci.nsIFile); - dir.append("minidumps"); - return dir; - } - - /** - * Removes a file from a directory. This is a no-op if the file does not - * exist. - * - * @param directory - * The nsIFile representing the directory to remove from. - * @param filename - * A string for the file to remove from the directory. - */ - function removeFile(directory, filename) { - let file = directory.clone(); - file.append(filename); - if (file.exists()) { - file.remove(false); - } - } - - // This frame script is injected into the remote browser, and used to - // intentionally crash the tab. We crash by using js-ctypes and dereferencing - // a bad pointer. The crash should happen immediately upon loading this - // frame script. - let frame_script = () => { - const Cu = Components.utils; - Cu.import("resource://gre/modules/ctypes.jsm"); - - let dies = function() { - privateNoteIntentionalCrash(); - let zero = new ctypes.intptr_t(8); - let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t)); - badptr.contents - }; - - dump("Et tu, Brute?"); - dies(); - } - - let crashCleanupPromise = new Promise((resolve, reject) => { - let observer = (subject, topic, data) => { - is(topic, 'ipc:content-shutdown', 'Received correct observer topic.'); - ok(subject instanceof Ci.nsIPropertyBag2, - 'Subject implements nsIPropertyBag2.'); - // we might see this called as the process terminates due to previous tests. - // We are only looking for "abnormal" exits... - if (!subject.hasKey("abnormal")) { - info("This is a normal termination and isn't the one we are looking for..."); - return; - } - - let dumpID; - if ('nsICrashReporter' in Ci) { - dumpID = subject.getPropertyAsAString('dumpID'); - ok(dumpID, "dumpID is present and not an empty string"); - } - - if (dumpID) { - let minidumpDirectory = getMinidumpDirectory(); - removeFile(minidumpDirectory, dumpID + '.dmp'); - removeFile(minidumpDirectory, dumpID + '.extra'); - } - - Services.obs.removeObserver(observer, 'ipc:content-shutdown'); - info("Crash cleaned up"); - resolve(); - }; - - Services.obs.addObserver(observer, 'ipc:content-shutdown'); - }); - - let aboutTabCrashedLoadPromise = new Promise((resolve, reject) => { - browser.addEventListener("AboutTabCrashedLoad", function onCrash() { - browser.removeEventListener("AboutTabCrashedLoad", onCrash, false); - info("about:tabcrashed loaded"); - resolve(); - }, false, true); - }); - - // This frame script will crash the remote browser as soon as it is - // evaluated. - let mm = browser.messageManager; - mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", false); - return Promise.all([crashCleanupPromise, aboutTabCrashedLoadPromise]).then(() => { - let tab = gBrowser.getTabForBrowser(browser); - is(tab.getAttribute("crashed"), "true", "Tab should be marked as crashed"); - }); -} - // Write DOMSessionStorage data to the given browser. function modifySessionStorage(browser, data, options = {}) { return ContentTask.spawn(browser, [data, options], function* ([data, options]) { diff --git a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm index 4b7e03c80aef..2dcf60ad88f1 100644 --- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm +++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm @@ -17,6 +17,7 @@ this.EXPORTED_SYMBOLS = [ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; +Cu.import("resource://gre/modules/AppConstants.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Task.jsm"); @@ -458,5 +459,147 @@ this.BrowserTestUtils = { tab.ownerDocument.defaultView.gBrowser.removeTab(tab); } }); - } + }, + + /** + * Crashes a remote browser tab and cleans up the generated minidumps. + * Resolves with the data from the .extra file (the crash annotations). + * + * @param (Browser) browser + * A remote element. Must not be null. + * + * @returns (Promise) + * @resolves An Object with key-value pairs representing the data from the + * crash report's extra file (if applicable). + */ + crashBrowser: Task.async(function*(browser) { + let extra = {}; + let KeyValueParser = {}; + if (AppConstants.MOZ_CRASHREPORTER) { + Cu.import("resource://gre/modules/KeyValueParser.jsm", KeyValueParser); + } + + if (!browser.isRemoteBrowser) { + throw new Error(" needs to be remote in order to crash"); + } + + /** + * Returns the directory where crash dumps are stored. + * + * @return nsIFile + */ + function getMinidumpDirectory() { + let dir = Services.dirsvc.get('ProfD', Ci.nsIFile); + dir.append("minidumps"); + return dir; + } + + /** + * Removes a file from a directory. This is a no-op if the file does not + * exist. + * + * @param directory + * The nsIFile representing the directory to remove from. + * @param filename + * A string for the file to remove from the directory. + */ + function removeFile(directory, filename) { + let file = directory.clone(); + file.append(filename); + if (file.exists()) { + file.remove(false); + } + } + + // This frame script is injected into the remote browser, and used to + // intentionally crash the tab. We crash by using js-ctypes and dereferencing + // a bad pointer. The crash should happen immediately upon loading this + // frame script. + let frame_script = () => { + const Cu = Components.utils; + Cu.import("resource://gre/modules/ctypes.jsm"); + + let dies = function() { + privateNoteIntentionalCrash(); + let zero = new ctypes.intptr_t(8); + let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t)); + badptr.contents + }; + + dump("\nEt tu, Brute?\n"); + dies(); + } + + let crashCleanupPromise = new Promise((resolve, reject) => { + let observer = (subject, topic, data) => { + if (topic != "ipc:content-shutdown") { + return reject("Received incorrect observer topic: " + topic); + } + if (!(subject instanceof Ci.nsIPropertyBag2)) { + return reject("Subject did not implement nsIPropertyBag2"); + } + // we might see this called as the process terminates due to previous tests. + // We are only looking for "abnormal" exits... + if (!subject.hasKey("abnormal")) { + dump("\nThis is a normal termination and isn't the one we are looking for...\n"); + return; + } + + let dumpID; + if ('nsICrashReporter' in Ci) { + dumpID = subject.getPropertyAsAString('dumpID'); + if (!dumpID) { + return reject("dumpID was not present despite crash reporting " + + "being enabled"); + } + } + + if (dumpID) { + let minidumpDirectory = getMinidumpDirectory(); + let extrafile = minidumpDirectory.clone(); + extrafile.append(dumpID + '.extra'); + if (extrafile.exists()) { + dump(`\nNo .extra file for dumpID: ${dumpID}\n`); + if (AppConstants.MOZ_CRASHREPORTER) { + extra = KeyValueParser.parseKeyValuePairsFromFile(extrafile); + } else { + dump('\nCrashReporter not enabled - will not return any extra data\n'); + } + } + + removeFile(minidumpDirectory, dumpID + '.dmp'); + removeFile(minidumpDirectory, dumpID + '.extra'); + } + + Services.obs.removeObserver(observer, 'ipc:content-shutdown'); + dump("\nCrash cleaned up\n"); + resolve(); + }; + + Services.obs.addObserver(observer, 'ipc:content-shutdown', false); + }); + + let aboutTabCrashedLoadPromise = new Promise((resolve, reject) => { + browser.addEventListener("AboutTabCrashedLoad", function onCrash() { + browser.removeEventListener("AboutTabCrashedLoad", onCrash, false); + dump("\nabout:tabcrashed loaded\n"); + resolve(); + }, false, true); + }); + + // This frame script will crash the remote browser as soon as it is + // evaluated. + let mm = browser.messageManager; + mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", false); + + yield Promise.all([crashCleanupPromise, aboutTabCrashedLoadPromise]); + + let gBrowser = browser.ownerDocument.defaultView.gBrowser; + let tab = gBrowser.getTabForBrowser(browser); + if (tab.getAttribute("crashed") != "true") { + throw new Error("Tab should be marked as crashed"); + } + + return extra; + }), }; diff --git a/toolkit/content/tests/browser/browser_content_url_annotation.js b/toolkit/content/tests/browser/browser_content_url_annotation.js index cd42f99b0b62..62667651ccc7 100644 --- a/toolkit/content/tests/browser/browser_content_url_annotation.js +++ b/toolkit/content/tests/browser/browser_content_url_annotation.js @@ -9,72 +9,6 @@ // Running this test in ASAN is slow. requestLongerTimeout(2); -/** - * Returns a Promise that resolves once a remote has experienced - * a crash. Resolves with the data from the .extra file (the crash annotations). - * - * @param browser - * The that will crash - * @return Promise - */ -function crashBrowser(browser) { - let kv = {}; - Cu.import("resource://gre/modules/KeyValueParser.jsm", kv); - // This frame script is injected into the remote browser, and used to - // intentionally crash the tab. We crash by using js-ctypes and dereferencing - // a bad pointer. The crash should happen immediately upon loading this - // frame script. - let frame_script = () => { - const Cu = Components.utils; - Cu.import("resource://gre/modules/ctypes.jsm"); - - let dies = function() { - privateNoteIntentionalCrash(); - let zero = new ctypes.intptr_t(8); - let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t)); - let crash = badptr.contents; - }; - - dump("Et tu, Brute?"); - dies(); - }; - - function checkSubject(subject, data) { - return subject instanceof Ci.nsIPropertyBag2 && - subject.hasKey("abnormal"); - }; - let crashPromise = TestUtils.topicObserved('ipc:content-shutdown', - checkSubject); - let crashDataPromise = crashPromise.then(([subject, data]) => { - ok(subject instanceof Ci.nsIPropertyBag2); - - let dumpID; - if ('nsICrashReporter' in Ci) { - dumpID = subject.getPropertyAsAString('dumpID'); - ok(dumpID, "dumpID is present and not an empty string"); - } - - let extra = null; - if (dumpID) { - let minidumpDirectory = getMinidumpDirectory(); - let extrafile = minidumpDirectory.clone(); - extrafile.append(dumpID + '.extra'); - ok(extrafile.exists(), 'found .extra file'); - extra = kv.parseKeyValuePairsFromFile(extrafile); - removeFile(minidumpDirectory, dumpID + '.dmp'); - removeFile(minidumpDirectory, dumpID + '.extra'); - } - - return extra; - }); - - // This frame script will crash the remote browser as soon as it is - // evaluated. - let mm = browser.messageManager; - mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", false); - return crashDataPromise; -} - /** * Removes a file from a directory. This is a no-op if the file does not * exist. @@ -130,7 +64,7 @@ add_task(function* test_content_url_annotation() { yield promise; // Crash the tab - let annotations = yield crashBrowser(browser); + let annotations = yield BrowserTestUtils.crashBrowser(browser); ok("URL" in annotations, "annotated a URL"); is(annotations.URL, redirect_url, From 226e9b91b6f208d6e4648c109aa5ad3e298db2af Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 30 Sep 2015 17:50:27 -0400 Subject: [PATCH 28/60] Bug 1110511 - Regression tests. r=felipe --HG-- extra : commitid : Bj6HzQgu0se extra : rebase_source : 67229249a62b7e2898b953ecb58a575ca759a0b7 --- browser/base/content/test/general/browser.ini | 2 + .../test/general/browser_aboutTabCrashed.js | 335 ++++++++++++++++++ 2 files changed, 337 insertions(+) create mode 100644 browser/base/content/test/general/browser_aboutTabCrashed.js diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 41a5b611273c..4b956cfd7122 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -525,3 +525,5 @@ support-files = readerModeArticle.html [browser_domFullscreen_fullscreenMode.js] [browser_menuButtonBadgeManager.js] +[browser_aboutTabCrashed.js] +skip-if = !e10s || !crashreporter diff --git a/browser/base/content/test/general/browser_aboutTabCrashed.js b/browser/base/content/test/general/browser_aboutTabCrashed.js new file mode 100644 index 000000000000..bacf9d54441f --- /dev/null +++ b/browser/base/content/test/general/browser_aboutTabCrashed.js @@ -0,0 +1,335 @@ +"use strict"; + +let { TabCrashReporter } = + Cu.import("resource:///modules/ContentCrashReporters.jsm"); + +const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs"; +const PAGE = "data:text/html,A%20regular,%20everyday,%20normal%20page."; +const COMMENTS = "Here's my test comment!"; +const EMAIL = "foo@privacy.com"; + +/** + * For an nsIPropertyBag, returns the value for a given + * key. + * + * @param bag + * The nsIPropertyBag to retrieve the value from + * @param key + * The key that we want to get the value for from the + * bag + * @returns The value corresponding to the key from the bag, + * or null if the value could not be retrieved (for + * example, if no value is set at that key). +*/ +function getPropertyBagValue(bag, key) { + try { + let val = bag.getProperty(key); + return val; + } catch(e if e.result == Cr.NS_ERROR_FAILURE) {} + + return null; +} + +/** + * Returns a Promise that resolves once a crash report has + * been submitted. This function will also test the crash + * reports extra data to see if it matches expectedExtra. + * + * @param expectedExtra + * An Object whose key-value pairs will be compared + * against the key-value pairs in the extra data of the + * crash report. A test failure will occur if there is + * a mismatch. + * + * Note that this will only check the values that exist + * in expectedExtra. It's possible that the crash report + * will contain other extra information that is not + * compared against. + * @returns Promise + */ +function promiseCrashReport(expectedExtra) { + return Task.spawn(function*() { + info("Starting wait on crash-report-status"); + let [subject, data] = + yield TestUtils.topicObserved("crash-report-status", (subject, data) => { + return data == "success"; + }); + info("Topic observed!"); + + if (!(subject instanceof Ci.nsIPropertyBag2)) { + throw new Error("Subject was not a Ci.nsIPropertyBag2"); + } + + let remoteID = getPropertyBagValue(subject, "serverCrashID"); + if (!remoteID) { + throw new Error("Report should have a server ID"); + } + + let file = Cc["@mozilla.org/file/local;1"] + .createInstance(Ci.nsILocalFile); + file.initWithPath(Services.crashmanager._submittedDumpsDir); + file.append(remoteID + ".txt"); + if (!file.exists()) { + throw new Error("Report should have been received by the server"); + } + + file.remove(false); + + let extra = getPropertyBagValue(subject, "extra"); + if (!(extra instanceof Ci.nsIPropertyBag2)) { + throw new Error("extra was not a Ci.nsIPropertyBag2"); + } + + info("Iterating crash report extra keys"); + let enumerator = extra.enumerator; + while (enumerator.hasMoreElements()) { + let key = enumerator.getNext().QueryInterface(Ci.nsIProperty).name; + let value = extra.getPropertyAsAString(key); + if (key in expectedExtra) { + is(value, expectedExtra[key], + `Crash report had the right extra value for ${key}`); + } + } + }); +} + +/** + * Sets up the browser to send crash reports to the local crash report + * testing server. + */ +add_task(function* setup() { + // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables crash + // reports. This test needs them enabled. The test also needs a mock + // report server, and fortunately one is already set up by toolkit/ + // crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL, + // which CrashSubmit.jsm uses as a server override. + let env = Cc["@mozilla.org/process/environment;1"] + .getService(Components.interfaces.nsIEnvironment); + let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT"); + let serverUrl = env.get("MOZ_CRASHREPORTER_URL"); + env.set("MOZ_CRASHREPORTER_NO_REPORT", ""); + env.set("MOZ_CRASHREPORTER_URL", SERVER_URL); + + registerCleanupFunction(function() { + env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport); + env.set("MOZ_CRASHREPORTER_URL", serverUrl); + }); +}); + +/** + * This function returns a Promise that resolves once the following + * actions have taken place: + * + * 1) A new tab is opened up at PAGE + * 2) The tab is crashed + * 3) The about:tabcrashed page's fields are set in accordance with + * fieldValues + * 4) The tab is restored + * 5) A crash report is received from the testing server + * 6) Any tab crash prefs that were overwritten are reset + * + * @param fieldValues + * An Object describing how to set the about:tabcrashed + * fields. The following properties are accepted: + * + * comments (String) + * The comments to put in the comment textarea + * email (String) + * The email address to put in the email address input + * emailMe (bool) + * The checked value of the "Email me" checkbox + * includeURL (bool) + * The checked value of the "Include URL" checkbox + * + * If any of these fields are missing, the defaults from + * the user preferences are used. + * @param expectedExtra + * An Object describing the expected values that the submitted + * crash report's extra data should contain. + * @returns Promise + */ +function crashTabTestHelper(fieldValues, expectedExtra) { + return BrowserTestUtils.withNewTab({ + gBrowser, + url: PAGE, + }, function*(browser) { + let prefs = TabCrashReporter.prefs; + let originalSendReport = prefs.getBoolPref("sendReport"); + let originalEmailMe = prefs.getBoolPref("emailMe"); + let originalIncludeURL = prefs.getBoolPref("includeURL"); + let originalEmail = prefs.getCharPref("email"); + + let tab = gBrowser.getTabForBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); + let doc = browser.contentDocument; + + // Since about:tabcrashed will run in the parent process, we can safely + // manipulate its DOM nodes directly + let comments = doc.getElementById("comments"); + let email = doc.getElementById("email"); + let emailMe = doc.getElementById("emailMe"); + let includeURL = doc.getElementById("includeURL"); + + if (fieldValues.hasOwnProperty("comments")) { + comments.value = fieldValues.comments; + } + + if (fieldValues.hasOwnProperty("email")) { + email.value = fieldValues.email; + } + + if (fieldValues.hasOwnProperty("emailMe")) { + emailMe.checked = fieldValues.emailMe; + } + + if (fieldValues.hasOwnProperty("includeURL")) { + includeURL.checked = fieldValues.includeURL; + } + + let crashReport = promiseCrashReport(expectedExtra); + let restoreTab = browser.contentDocument.getElementById("restoreTab"); + restoreTab.click(); + yield BrowserTestUtils.waitForEvent(tab, "SSTabRestored"); + yield crashReport; + + // Submitting the crash report may have set some prefs regarding how to + // send tab crash reports. Let's reset them for the next test. + prefs.setBoolPref("sendReport", originalSendReport); + prefs.setBoolPref("emailMe", originalEmailMe); + prefs.setBoolPref("includeURL", originalIncludeURL); + prefs.setCharPref("email", originalEmail); + }); +} + +/** + * Tests what we send with the crash report by default. By default, we do not + * send any comments, the URL of the crashing page, or the email address of + * the user. + */ +add_task(function* test_default() { + yield crashTabTestHelper({}, { + "Comments": "", + "URL": "", + "Email": "", + }); +}); + +/** + * Test just sending a comment. + */ +add_task(function* test_just_a_comment() { + yield crashTabTestHelper({ + comments: COMMENTS, + }, { + "Comments": COMMENTS, + "URL": "", + "Email": "", + }); +}); + +/** + * Test that we don't send email if emailMe is unchecked + */ +add_task(function* test_no_email() { + yield crashTabTestHelper({ + email: EMAIL, + emailMe: false, + }, { + "Comments": "", + "URL": "", + "Email": "", + }); +}); + +/** + * Test that we can send an email address if emailMe is checked + */ +add_task(function* test_yes_email() { + yield crashTabTestHelper({ + email: EMAIL, + emailMe: true, + }, { + "Comments": "", + "URL": "", + "Email": EMAIL, + }); +}); + +/** + * Test that we will send the URL of the page if includeURL is checked. + */ +add_task(function* test_send_URL() { + yield crashTabTestHelper({ + includeURL: true, + }, { + "Comments": "", + "URL": PAGE, + "Email": "", + }); +}); + +/** + * Test that we can send comments, the email address, and the URL + */ +add_task(function* test_send_all() { + yield crashTabTestHelper({ + includeURL: true, + emailMe: true, + email: EMAIL, + comments: COMMENTS, + }, { + "Comments": COMMENTS, + "URL": PAGE, + "Email": EMAIL, + }); +}); + +/** + * Test that if we have an email address stored in prefs, and we decide + * not to submit the email address in the next crash report, that we + * clear the email address. + */ +add_task(function* test_clear_email() { + return BrowserTestUtils.withNewTab({ + gBrowser, + url: PAGE, + }, function*(browser) { + let prefs = TabCrashReporter.prefs; + let originalSendReport = prefs.getBoolPref("sendReport"); + let originalEmailMe = prefs.getBoolPref("emailMe"); + let originalIncludeURL = prefs.getBoolPref("includeURL"); + let originalEmail = prefs.getCharPref("email"); + + // Pretend that we stored an email address from the previous + // crash + prefs.setCharPref("email", EMAIL); + prefs.setBoolPref("emailMe", true); + + let tab = gBrowser.getTabForBrowser(browser); + yield BrowserTestUtils.crashBrowser(browser); + let doc = browser.contentDocument; + + // Since about:tabcrashed will run in the parent process, we can safely + // manipulate its DOM nodes directly + let emailMe = doc.getElementById("emailMe"); + emailMe.checked = false; + + let crashReport = promiseCrashReport({ + Email: "", + }); + + let restoreTab = browser.contentDocument.getElementById("restoreTab"); + restoreTab.click(); + yield BrowserTestUtils.waitForEvent(tab, "SSTabRestored"); + yield crashReport; + + is(prefs.getCharPref("email"), "", "No email address should be stored"); + + // Submitting the crash report may have set some prefs regarding how to + // send tab crash reports. Let's reset them for the next test. + prefs.setBoolPref("sendReport", originalSendReport); + prefs.setBoolPref("emailMe", originalEmailMe); + prefs.setBoolPref("includeURL", originalIncludeURL); + prefs.setCharPref("email", originalEmail); + }); +}); From efc38b2ecafd7446ec3b2b6b8a3f1d035edacb3c Mon Sep 17 00:00:00 2001 From: Michael Henretty Date: Mon, 5 Oct 2015 17:18:52 +0200 Subject: [PATCH 29/60] Bug 1210740 - Expose tracking protection setting to Gaia, r=fabrice --- b2g/app/b2g.js | 2 +- b2g/chrome/content/settings.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 8295494dc0e0..c4d260aadc8e 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -385,7 +385,7 @@ pref("urlclassifier.gethash.timeout_ms", 5000); pref("urlclassifier.max-complete-age", 2700); // Tracking protection -pref("privacy.trackingprotection.enabled", true); +pref("privacy.trackingprotection.enabled", false); pref("privacy.trackingprotection.pbmode.enabled", false); #endif diff --git a/b2g/chrome/content/settings.js b/b2g/chrome/content/settings.js index 107544bd0358..ab7074a47544 100644 --- a/b2g/chrome/content/settings.js +++ b/b2g/chrome/content/settings.js @@ -671,6 +671,7 @@ var settingsToObserve = { 'mms.debugging.enabled': false, 'network.debugging.enabled': false, 'privacy.donottrackheader.enabled': false, + 'privacy.trackingprotection.enabled': false, 'ril.debugging.enabled': false, 'ril.radio.disabled': false, 'ril.mms.requestReadReport.enabled': { From c44fd52108afae5f53eb2b10007bfc78c04a33ef Mon Sep 17 00:00:00 2001 From: Kevin Grandon Date: Mon, 5 Oct 2015 08:36:00 +0200 Subject: [PATCH 30/60] Bug 1211481 - Expose screenX and screenY to context menu events. r=fabrice --- dom/browser-element/BrowserElementChildPreload.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index d4adc585a854..9eb20d888bfa 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -916,6 +916,8 @@ BrowserElementChild.prototype = { // Pass along the position where the context menu should be located menuData.clientX = e.clientX; menuData.clientY = e.clientY; + menuData.screenX = e.screenX; + menuData.screenY = e.screenY; // The value returned by the contextmenu sync call is true if the embedder // called preventDefault() on its contextmenu event. From dac84a513c97f00fc1955e4004f03a2fc13c2417 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Tue, 6 Oct 2015 09:37:23 -0400 Subject: [PATCH 31/60] Backout changeset 7635a2e4fa64 for regressions in bug 1208790. --HG-- extra : commitid : 9glmrm88OoL extra : rebase_source : 16975787fcb93012b4b130a43ad98646646a28fb --- .../layout/preference_search_tip.xml | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/mobile/android/base/resources/layout/preference_search_tip.xml b/mobile/android/base/resources/layout/preference_search_tip.xml index 0ff11e18cb50..c59e7c483f56 100644 --- a/mobile/android/base/resources/layout/preference_search_tip.xml +++ b/mobile/android/base/resources/layout/preference_search_tip.xml @@ -2,14 +2,16 @@ - + + + android:paddingRight="6dip" + android:layout_weight="1"/> - + + + From 37769f52fe43c254d8c0a18097c9a1944289513f Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Tue, 6 Oct 2015 09:41:49 -0400 Subject: [PATCH 32/60] Bug 1208790 - Add lint ignore for compound drawables in search preference. r=me The regression is fixed by the backout of bug 1175354 and this should ensure it doesn't happen again. --HG-- extra : commitid : 7mVa6zNb0uq extra : rebase_source : b83744e2fc37fbf41a1d91104861b3bc41c00a05 --- mobile/android/base/resources/layout/preference_search_tip.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mobile/android/base/resources/layout/preference_search_tip.xml b/mobile/android/base/resources/layout/preference_search_tip.xml index c59e7c483f56..e03b171b468a 100644 --- a/mobile/android/base/resources/layout/preference_search_tip.xml +++ b/mobile/android/base/resources/layout/preference_search_tip.xml @@ -3,7 +3,10 @@ - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + Date: Mon, 5 Oct 2015 13:55:22 +0100 Subject: [PATCH 33/60] Bug 1211255 - fix downloads on fennec, r=mak --HG-- extra : commitid : DX1O1HFeLdH --- toolkit/mozapps/downloads/DownloadUtils.jsm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/mozapps/downloads/DownloadUtils.jsm b/toolkit/mozapps/downloads/DownloadUtils.jsm index 9a106ef1cab4..2c4875947255 100644 --- a/toolkit/mozapps/downloads/DownloadUtils.jsm +++ b/toolkit/mozapps/downloads/DownloadUtils.jsm @@ -483,7 +483,7 @@ this.DownloadUtils = { if (aBytes === Infinity) { aBytes = "Infinity"; } else { - if (Intl) { + if (typeof Intl != "undefined") { aBytes = getLocaleNumberFormat(fractionDigits) .format(aBytes); } else if (gDecimalSymbol != ".") { From 7b85e483f38128219c8d30b23d7c2a198404f16d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:12:38 +0200 Subject: [PATCH 34/60] Bug 1211435: Rename some internal classes of Bluetooth's A2DP manager, r=shuang --- .../bluedroid/BluetoothA2dpManager.cpp | 18 +++++++++--------- dom/bluetooth/bluedroid/BluetoothA2dpManager.h | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp index b9cabe1b641b..3296823b83ad 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp @@ -86,11 +86,11 @@ AvStatusToSinkString(BluetoothA2dpConnectionState aState, nsAString& aString) } } -class BluetoothA2dpManager::InitA2dpResultHandler final +class BluetoothA2dpManager::InitResultHandler final : public BluetoothA2dpResultHandler { public: - InitA2dpResultHandler(BluetoothProfileResultHandler* aRes) + InitResultHandler(BluetoothProfileResultHandler* aRes) : mRes(aRes) { } @@ -172,7 +172,7 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes) } BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get(); - sBtA2dpInterface->Init(a2dpManager, new InitA2dpResultHandler(aRes)); + sBtA2dpInterface->Init(a2dpManager, new InitResultHandler(aRes)); } BluetoothA2dpManager::~BluetoothA2dpManager() @@ -227,11 +227,11 @@ BluetoothA2dpManager::Get() return sBluetoothA2dpManager; } -class BluetoothA2dpManager::CleanupA2dpResultHandler final +class BluetoothA2dpManager::CleanupResultHandler final : public BluetoothA2dpResultHandler { public: - CleanupA2dpResultHandler(BluetoothProfileResultHandler* aRes) + CleanupResultHandler(BluetoothProfileResultHandler* aRes) : mRes(aRes) { } @@ -260,11 +260,11 @@ private: nsRefPtr mRes; }; -class BluetoothA2dpManager::CleanupA2dpResultHandlerRunnable final +class BluetoothA2dpManager::CleanupResultHandlerRunnable final : public nsRunnable { public: - CleanupA2dpResultHandlerRunnable(BluetoothProfileResultHandler* aRes) + CleanupResultHandlerRunnable(BluetoothProfileResultHandler* aRes) : mRes(aRes) { } @@ -289,11 +289,11 @@ BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes) MOZ_ASSERT(NS_IsMainThread()); if (sBtA2dpInterface) { - sBtA2dpInterface->Cleanup(new CleanupA2dpResultHandler(aRes)); + sBtA2dpInterface->Cleanup(new CleanupResultHandler(aRes)); } else if (aRes) { // We dispatch a runnable here to make the profile resource handler // behave as if A2DP was initialized. - nsRefPtr r = new CleanupA2dpResultHandlerRunnable(aRes); + nsRefPtr r = new CleanupResultHandlerRunnable(aRes); if (NS_FAILED(NS_DispatchToMainThread(r))) { BT_LOGR("Failed to dispatch cleanup-result-handler runnable"); } diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h index f4ac3cd41d67..44a4bb355149 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h +++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h @@ -47,11 +47,11 @@ protected: virtual ~BluetoothA2dpManager(); private: - class CleanupA2dpResultHandler; - class CleanupA2dpResultHandlerRunnable; + class CleanupResultHandler; + class CleanupResultHandlerRunnable; class ConnectResultHandler; class DisconnectResultHandler; - class InitA2dpResultHandler; + class InitResultHandler; class OnErrorProfileResultHandlerRunnable; BluetoothA2dpManager(); From 5db5ee8b4c55a7d31468dab7b0ef4a542bda4884 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:12:38 +0200 Subject: [PATCH 35/60] Bug 1211435: Rename some internal classes of Bluetooth's AVRCP manager, r=shuang --- .../bluedroid/BluetoothAvrcpManager.cpp | 34 ++++++++----------- .../bluedroid/BluetoothAvrcpManager.h | 6 ++-- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp index 7b36f29813d8..461968cac8db 100644 --- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp @@ -118,11 +118,11 @@ BluetoothAvrcpManager::Reset() mPlayStatus = ControlPlayStatus::PLAYSTATUS_STOPPED; } -class BluetoothAvrcpManager::InitAvrcpResultHandler final +class BluetoothAvrcpManager::InitResultHandler final : public BluetoothAvrcpResultHandler { public: - InitAvrcpResultHandler(BluetoothProfileResultHandler* aRes) + InitResultHandler(BluetoothProfileResultHandler* aRes) : mRes(aRes) { } @@ -209,7 +209,7 @@ BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes) } BluetoothAvrcpManager* avrcpManager = BluetoothAvrcpManager::Get(); - sBtAvrcpInterface->Init(avrcpManager, new InitAvrcpResultHandler(aRes)); + sBtAvrcpInterface->Init(avrcpManager, new InitResultHandler(aRes)); } BluetoothAvrcpManager::~BluetoothAvrcpManager() @@ -245,11 +245,11 @@ BluetoothAvrcpManager::Get() return sBluetoothAvrcpManager; } -class BluetoothAvrcpManager::CleanupAvrcpResultHandler final +class BluetoothAvrcpManager::CleanupResultHandler final : public BluetoothAvrcpResultHandler { public: - CleanupAvrcpResultHandler(BluetoothProfileResultHandler* aRes) + CleanupResultHandler(BluetoothProfileResultHandler* aRes) : mRes(aRes) { } @@ -285,25 +285,19 @@ private: nsRefPtr mRes; }; -class BluetoothAvrcpManager::CleanupAvrcpResultHandlerRunnable final +class BluetoothAvrcpManager::CleanupResultHandlerRunnable final : public nsRunnable { public: - CleanupAvrcpResultHandlerRunnable(BluetoothProfileResultHandler* aRes) + CleanupResultHandlerRunnable(BluetoothProfileResultHandler* aRes) : mRes(aRes) - { } + { + MOZ_ASSERT(mRes); + } NS_IMETHOD Run() override { - sBtAvrcpInterface = nullptr; - if (sBtAvrcpInterface) { - sBtAvrcpInterface->Cleanup(new CleanupAvrcpResultHandler(mRes)); - } else if (mRes) { - /* Not all backends support AVRCP. If it's not available - * we signal success from here. - */ - mRes->Deinit(); - } + mRes->Deinit(); return NS_OK; } @@ -319,11 +313,11 @@ BluetoothAvrcpManager::DeinitAvrcpInterface(BluetoothProfileResultHandler* aRes) MOZ_ASSERT(NS_IsMainThread()); if (sBtAvrcpInterface) { - sBtAvrcpInterface->Cleanup(new CleanupAvrcpResultHandler(aRes)); + sBtAvrcpInterface->Cleanup(new CleanupResultHandler(aRes)); } else if (aRes) { // We dispatch a runnable here to make the profile resource handler - // behave as if A2DP was initialized. - nsRefPtr r = new CleanupAvrcpResultHandlerRunnable(aRes); + // behave as if AVRCP was initialized. + nsRefPtr r = new CleanupResultHandlerRunnable(aRes); if (NS_FAILED(NS_DispatchToMainThread(r))) { BT_LOGR("Failed to dispatch cleanup-result-handler runnable"); } diff --git a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h index 3be51ab1dddd..a4bc1913c291 100644 --- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h +++ b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h @@ -60,11 +60,11 @@ protected: virtual ~BluetoothAvrcpManager(); private: - class CleanupAvrcpResultHandler; - class CleanupAvrcpResultHandlerRunnable; + class CleanupResultHandler; + class CleanupResultHandlerRunnable; class ConnectRunnable; class DisconnectRunnable; - class InitAvrcpResultHandler; + class InitResultHandler; class OnErrorProfileResultHandlerRunnable; BluetoothAvrcpManager(); From bc620fb2b2f890ed66cbb44ad3d46b9b979f7b77 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 6 Oct 2015 10:12:38 +0200 Subject: [PATCH 36/60] Bug 1211435: Cleanup AVRCP interfaces when Bluetooth adapter gets switched off, r=shuang Cleaning up AVRCP was forgotten in bug 1199110. --- dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index 2e7ae85616bb..ad42626a29a8 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -1890,9 +1890,11 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState) if (!mEnabled) { static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = { - BluetoothHfpManager::DeinitHfpInterface, + // Cleanup interfaces in opposite order to initialization. + BluetoothGattManager::DeinitGattInterface, + BluetoothAvrcpManager::DeinitAvrcpInterface, BluetoothA2dpManager::DeinitA2dpInterface, - BluetoothGattManager::DeinitGattInterface + BluetoothHfpManager::DeinitHfpInterface }; // Return error if BluetoothService is unavailable From 78d15c3185d8d2f545d571b3a2de63b81a452d63 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 6 Oct 2015 02:10:19 -0700 Subject: [PATCH 37/60] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/7989af3dde0e Author: Johan Lorenzo Desc: Merge pull request #32235 from JohanLorenzo/bug-1187330-2 Bug 1187330 - You can't have engineering apps with the spark distro ======== https://hg.mozilla.org/integration/gaia-central/rev/ada3ce43329b Author: Johan Lorenzo Desc: Bug 1187330 - You can't have engineering apps with the spark distro --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 5ddf2d08a8ac..7291c05d0782 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "8c58d628dcccdfccd238d5f128dfce37795a981f", + "git_revision": "0f59a94987f15f87f0b0115d53bdad4cb6ace57e", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "e83090296c16cd09dc5ed5bb2de157547beba4c9", + "revision": "7989af3dde0e654783c2084eec9393c4645bf506", "repo_path": "integration/gaia-central" } From 16670c711f88676feedfb63658de74123cfab52d Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 6 Oct 2015 02:13:46 -0700 Subject: [PATCH 38/60] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index f3ac2b4a8475..0cfc4586cab9 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index c3a6f3fafc78..790f466a0e5e 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index aa844989d7e6..bb1284e66272 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 4eef3aa971eb..562c50a3d5e6 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 8f829599e9ff..305e47011366 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 335062e5849f..b3b897baba77 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index aa844989d7e6..bb1284e66272 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 7cd005a3fab7..588a08e0861f 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4-kk/sources.xml b/b2g/config/nexus-4-kk/sources.xml index edc3a358faa9..44f6366bdd1c 100644 --- a/b2g/config/nexus-4-kk/sources.xml +++ b/b2g/config/nexus-4-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 6f86326fd146..165e89f2e612 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -18,7 +18,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index e573739f3389..5dfb044d0d9e 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 5b34c7c45ff978429dd2b874414cd7cdf41482f7 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 6 Oct 2015 02:54:45 -0700 Subject: [PATCH 39/60] Bumping manifests a=b2g-bump --- b2g/config/emulator-kk/sources.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 305e47011366..7aa6adb12d2a 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -128,10 +128,10 @@ - + - + From b9514e3ffa06be3517d93a8c58dd637736f9ee9d Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 6 Oct 2015 03:01:52 -0700 Subject: [PATCH 40/60] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/1867d89c3747 Author: Fabien Cazenave Desc: Merge pull request #32232 from fabi1cazenave/value_selector_bug1211421 Bug 1211421 -