Bug 1011472 - Add audio alert for incoming call r=florian,standard8

This commit is contained in:
Adam Roach [:abr] 2014-06-26 18:55:03 -05:00
Родитель b8cc2a9367
Коммит f0203d7e00
6 изменённых файлов: 120 добавлений и 8 удалений

Просмотреть файл

@ -1512,6 +1512,7 @@ pref("image.mem.max_decoded_image_kb", 256000);
#ifdef MOZ_LOOP
pref("loop.server", "https://loop.services.mozilla.com");
pref("loop.do_not_disturb", false);
pref("loop.ringtone", "chrome://browser/content/loop/shared/sounds/Firefox-Long.ogg");
#endif
// serverURL to be assigned by services team

Просмотреть файл

@ -24,6 +24,9 @@ this.EXPORTED_SYMBOLS = ["injectLoopAPI"];
* @param {nsIDOMWindow} targetWindow The content window to attach the API.
*/
function injectLoopAPI(targetWindow) {
let ringer;
let ringerStopper;
let api = {
/**
* Sets and gets the "do not disturb" mode activation flag.
@ -149,6 +152,50 @@ function injectLoopAPI(targetWindow) {
value: function(prefName) {
return MozLoopService.getLoopCharPref(prefName);
}
},
/**
* Starts alerting the user about an incoming call
*/
startAlerting: {
enumerable: true,
configurable: true,
writable: true,
value: function() {
let chromeWindow = getChromeWindow(targetWindow);
chromeWindow.getAttention();
ringer = new chromeWindow.Audio();
ringer.src = Services.prefs.getCharPref("loop.ringtone");
ringer.loop = true;
ringer.load();
ringer.play();
targetWindow.document.addEventListener("visibilitychange",
ringerStopper = function(event) {
if (event.currentTarget.hidden) {
api.stopAlerting.value();
}
});
}
},
/**
* Stops alerting the user about an incoming call
*/
stopAlerting: {
enumerable: true,
configurable: true,
writable: true,
value: function() {
if (ringerStopper) {
targetWindow.document.removeEventListener("visibilitychange",
ringerStopper);
ringerStopper = null;
}
if (ringer) {
ringer.pause();
ringer = null;
}
}
}
};
@ -168,3 +215,12 @@ function injectLoopAPI(targetWindow) {
// Handle window.close correctly on the panel and chatbox.
hookWindowCloseForPanelClose(targetWindow);
}
function getChromeWindow(contentWin) {
return contentWin.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
}

Просмотреть файл

@ -53,8 +53,7 @@ loop.conversation = (function(OT, mozL10n) {
*/
handleDecline: function(event) {
event.preventDefault();
// XXX For now, we just close the window.
window.close();
this.model.trigger("decline");
}
});
@ -95,6 +94,7 @@ loop.conversation = (function(OT, mozL10n) {
routes: {
"incoming/:version": "incoming",
"call/accept": "accept",
"call/decline": "decline",
"call/ongoing": "conversation",
"call/ended": "ended"
},
@ -120,10 +120,14 @@ loop.conversation = (function(OT, mozL10n) {
* by the router from the URL.
*/
incoming: function(loopVersion) {
window.navigator.mozLoop.startAlerting();
this._conversation.set({loopVersion: loopVersion});
this._conversation.once("accept", function() {
this.navigate("call/accept", {trigger: true});
}.bind(this));
this._conversation.once("decline", function() {
this.navigate("call/decline", {trigger: true});
}.bind(this));
this.loadView(new IncomingCallView({model: this._conversation}));
},
@ -131,12 +135,22 @@ loop.conversation = (function(OT, mozL10n) {
* Accepts an incoming call.
*/
accept: function() {
window.navigator.mozLoop.stopAlerting();
this._conversation.initiate({
baseServerUrl: window.navigator.mozLoop.serverUrl,
outgoing: false
});
},
/**
* Declines an incoming call.
*/
decline: function() {
window.navigator.mozLoop.stopAlerting();
// XXX For now, we just close the window
window.close();
},
/**
* conversation is the route when the conversation is active. The start
* route should be navigated to first.

Двоичные данные
browser/components/loop/content/shared/sounds/Firefox-Long.ogg Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -21,6 +21,7 @@ browser.jar:
content/browser/loop/shared/libs/sjcl-dev20140604.js (content/shared/libs/sjcl-dev20140604.js)
content/browser/loop/shared/libs/token.js (content/shared/libs/token.js)
content/browser/loop/shared/libs/hawk-browser-2.2.1.js (content/shared/libs/hawk-browser-2.2.1.js)
content/browser/loop/shared/sounds/Firefox-Long.ogg (content/shared/sounds/Firefox-Long.ogg)
content/browser/loop/libs/l10n.js (content/libs/l10n.js)
content/browser/loop/js/desktopRouter.js (content/js/desktopRouter.js)
content/browser/loop/js/conversation.js (content/js/conversation.js)

Просмотреть файл

@ -26,6 +26,12 @@ describe("loop.conversation", function() {
window.navigator.mozLoop = {
get serverUrl() {
return "http://example.com";
},
startAlerting: function() {
},
stopAlerting: function() {
}
};
});
@ -119,6 +125,13 @@ describe("loop.conversation", function() {
sinon.assert.calledWithExactly(router.loadView,
sinon.match.instanceOf(loop.conversation.IncomingCallView));
});
it("should start alerting", function() {
sandbox.stub(window.navigator.mozLoop, "startAlerting");
router.incoming("fakeVersion");
sinon.assert.calledOnce(window.navigator.mozLoop.startAlerting);
});
});
describe("#accept", function() {
@ -131,6 +144,13 @@ describe("loop.conversation", function() {
outgoing: false
});
});
it("should stop alerting", function() {
sandbox.stub(window.navigator.mozLoop, "stopAlerting");
router.accept();
sinon.assert.calledOnce(window.navigator.mozLoop.stopAlerting);
});
});
describe("#conversation", function() {
@ -163,6 +183,25 @@ describe("loop.conversation", function() {
});
});
describe("#decline", function() {
beforeEach(function() {
sandbox.stub(window, "close");
});
it("should close the window", function() {
router.decline();
sinon.assert.calledOnce(window.close);
});
it("should stop alerting", function() {
sandbox.stub(window.navigator.mozLoop, "stopAlerting");
router.decline();
sinon.assert.calledOnce(window.navigator.mozLoop.stopAlerting);
});
});
describe("#ended", function() {
// XXX When the call is ended gracefully, we should check that we
// close connections nicely
@ -254,13 +293,14 @@ describe("loop.conversation", function() {
});
describe("#handleDecline", function() {
it("should close the window", function() {
sandbox.stub(window, "close");
it("should trigger an 'decline' conversation model event" ,
function(done) {
conversation.once("decline", function() {
done();
});
view.handleDecline({preventDefault: sandbox.spy()});
sinon.assert.calledOnce(window.close);
});
view.handleDecline({preventDefault: sandbox.spy()});
});
});
});
});