From 8bcd6b3e378114b7a6fd17aa3cababee5fed7939 Mon Sep 17 00:00:00 2001 From: Etienne Segonzac Date: Tue, 4 Sep 2012 11:23:13 +0200 Subject: [PATCH 1/2] Removing the dialer background service. The emergency dialer living in the lockscreen now has it's own minimal call screen. This also fix a focus issue between the attention screen and the lockscreen. --- apps/communications/dialer/background.html | 17 - apps/communications/dialer/index.html | 1 - apps/communications/dialer/js/background.js | 131 ------ .../communications/dialer/js/custom_dialog.js | 111 ----- apps/communications/dialer/js/dialer.js | 236 ++++++---- apps/communications/dialer/js/oncall.js | 431 +++++++++++------- apps/communications/dialer/oncall.html | 1 + apps/communications/manifest.webapp | 7 +- apps/system/emergency-call/index.html | 52 ++- apps/system/emergency-call/js/dialer.js | 63 ++- apps/system/emergency-call/style/dialer.css | 164 +++++++ .../images/ActionIcon_40x40_bluetooth.png | Bin 0 -> 2124 bytes .../ActionIcon_40x40_bluetooth_active.png | Bin 0 -> 2134 bytes .../style/images/ActionIcon_40x40_hangup.png | Bin 0 -> 1707 bytes apps/system/js/attention_screen.js | 16 +- 15 files changed, 695 insertions(+), 535 deletions(-) delete mode 100644 apps/communications/dialer/background.html delete mode 100644 apps/communications/dialer/js/background.js delete mode 100644 apps/communications/dialer/js/custom_dialog.js create mode 100644 apps/system/emergency-call/style/images/ActionIcon_40x40_bluetooth.png create mode 100644 apps/system/emergency-call/style/images/ActionIcon_40x40_bluetooth_active.png create mode 100644 apps/system/emergency-call/style/images/ActionIcon_40x40_hangup.png diff --git a/apps/communications/dialer/background.html b/apps/communications/dialer/background.html deleted file mode 100644 index f02cdbd97d65..000000000000 --- a/apps/communications/dialer/background.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Dialer Background Service - - - - - - - - - - - - diff --git a/apps/communications/dialer/index.html b/apps/communications/dialer/index.html index 4fa83fcc6c25..fe6d5a9a90fb 100755 --- a/apps/communications/dialer/index.html +++ b/apps/communications/dialer/index.html @@ -19,7 +19,6 @@ - diff --git a/apps/communications/dialer/js/background.js b/apps/communications/dialer/js/background.js deleted file mode 100644 index a701030a0bc5..000000000000 --- a/apps/communications/dialer/js/background.js +++ /dev/null @@ -1,131 +0,0 @@ -'use strict'; - -(function() { - var telephony = navigator.mozTelephony; - if (!telephony) { - return; - } - - /* === Setup === */ - var ringtonePlayer = new Audio(); - ringtonePlayer.loop = true; - - /* === Settings === */ - var activePhoneSound = true; - SettingsListener.observe('phone.ring.incoming', true, function(value) { - activePhoneSound = !!value; - }); - - var selectedPhoneSound = ''; - SettingsListener.observe('dialer.ringtone', 'classic.ogg', function(value) { - selectedPhoneSound = 'style/ringtones/' + value; - ringtonePlayer.src = selectedPhoneSound; - }); - - var activateVibration = false; - SettingsListener.observe('phone.vibration.incoming', false, function(value) { - activateVibration = !!value; - }); - - var preferredBrightness = 0.5; - SettingsListener.observe('screen.brightness', 0.5, function(value) { - preferredBrightness = parseFloat(value); - }); - - var callScreenDisplayed = false; - window.addEventListener('message', function messageListener(evt) { - if (evt.data == 'closing') { - callScreenDisplayed = false; - } - }); - - var screenState = 'locked'; - SettingsListener.observe('lockscreen.locked', false, function(value) { - if (value) { - screenState = 'locked'; - } else { - screenState = 'unlocked'; - } - }); - - var _ = navigator.mozL10n.get; - - /* === Incoming handling === */ - telephony.addEventListener('callschanged', function bs_incomingHandler(evt) { - // If the call screen is displayed we don't need - // to handle new incoming calls here - if (callScreenDisplayed) { - return; - } - - var call = null; - telephony.calls.some(function(aCall) { - if (aCall.state == 'incoming' || aCall.state == 'dialing') { - call = aCall; - return true; - } - return false; - }); - - if (!call) - return; - - var host = document.location.host; - var protocol = document.location.protocol; - var urlBase = protocol + '//' + host + '/dialer/oncall.html'; - window.open(urlBase + '#' + call.state + '?' + screenState, - 'call_screen', 'attention'); - - callScreenDisplayed = true; - - if (call.state != 'incoming') - return; - - var vibrateInterval = 0; - if (activateVibration) { - vibrateInterval = window.setInterval(function vibrate() { - if ('vibrate' in navigator) { - navigator.vibrate([200]); - } - }, 600); - } - - if (activePhoneSound && selectedPhoneSound) { - ringtonePlayer.play(); - } - - call.onstatechange = function callStateChange() { - call.onstatechange = null; - - ringtonePlayer.pause(); - window.clearInterval(vibrateInterval); - - // The call wasn't picked up - if (call.state == 'disconnected') { - navigator.mozApps.getSelf().onsuccess = function getSelfCB(evt) { - var app = evt.target.result; - - var iconURL = NotificationHelper.getIconURI(app); - - var notiClick = function() { - // Asking to launch itself - app.launch('#recents-view'); - }; - - Contacts.findByNumber(call.number, function lookupContact(contact) { - var title = _('missedCall'); - var sender = call.number.length ? call.number : _('unknown'); - - if (contact && contact.name) { - sender = contact.name; - } - - var body = _('from', {sender: sender}); - - NotificationHelper.send(title, body, iconURL, notiClick); - }); - }; - } - }; - }); -}()); diff --git a/apps/communications/dialer/js/custom_dialog.js b/apps/communications/dialer/js/custom_dialog.js deleted file mode 100644 index ca9a234dac95..000000000000 --- a/apps/communications/dialer/js/custom_dialog.js +++ /dev/null @@ -1,111 +0,0 @@ - -'use strict'; - -var CustomDialog = (function() { - - var screen = null; - var dialog = null; - var header = null; - var message = null; - var yes = null; - var no = null; - - return { - hide: function dialog_hide() { - if (screen === null) - return; - - document.body.removeChild(screen); - screen = null; - dialog = null; - header = null; - message = null; - yes = null; - no = null; - }, - - /** - * Method that shows the dialog - * @param {String} title the title of the dialog. null or empty for - * no title. - * @param {String} msg message for the dialog. - * @param {Object} cancel {title, callback} object when confirm. - * @param {Object} confirm {title, callback} object when cancel. - */ - show: function dialog_show(title, msg, cancel, confirm) { - if (screen === null) { - screen = document.createElement('section'); - screen.setAttribute('role', 'region'); - screen.id = 'dialog-screen'; - - dialog = document.createElement('div'); - dialog.id = 'dialog-dialog'; - dialog.setAttribute('role', 'dialog'); - screen.appendChild(dialog); - - var info = document.createElement('div'); - info.className = 'center'; - - if (title && title != '') { - header = document.createElement('h3'); - header.id = 'dialog-title'; - header.textContent = title; - info.appendChild(header); - } - - message = document.createElement('p'); - message.id = 'dialog-message'; - info.appendChild(message); - dialog.appendChild(info); - - var menu = document.createElement('menu'); - menu.dataset['items'] = 1; - - no = document.createElement('button'); - var noText = document.createTextNode(cancel.title); - no.appendChild(noText); - no.id = 'dialog-no'; - no.addEventListener('click', clickHandler); - menu.appendChild(no); - - if (confirm) { - menu.dataset['items'] = 2; - yes = document.createElement('button'); - var yesText = document.createTextNode(confirm.title); - yes.appendChild(yesText); - yes.id = 'dialog-yes'; - yes.className = 'negative'; - yes.addEventListener('click', clickHandler); - menu.appendChild(yes); - } - - dialog.appendChild(menu); - - document.body.appendChild(screen); - } - - // Put the message in the dialog. - // Note plain text since this may include text from - // untrusted app manifests, for example. - message.textContent = msg; - - // Make the screen visible - screen.classList.add('visible'); - - // This is the event listener function for the buttons - function clickHandler(evt) { - - // Hide the dialog - screen.classList.remove('visible'); - - // Call the appropriate callback, if it is defined - if (evt.target === yes && confirm.callback) { - confirm.callback(); - } else if (evt.target === no && cancel.callback) { - cancel.callback(); - } - } - } - }; -}()); - diff --git a/apps/communications/dialer/js/dialer.js b/apps/communications/dialer/js/dialer.js index 151492833cf3..b0d22cb443a8 100644 --- a/apps/communications/dialer/js/dialer.js +++ b/apps/communications/dialer/js/dialer.js @@ -1,83 +1,93 @@ 'use strict'; -document.addEventListener('mozvisibilitychange', function visibility(e) { - if (!document.mozHidden) { - RecentsDBManager.get(function(recents) { - Recents.render(recents); - }); +var CallHandler = (function callHandler() { + var telephony = navigator.mozTelephony; + var _ = navigator.mozL10n.get; + + var callScreenDisplayed = false; + var currentActivity = null; + + /* === Settings === */ + var screenState = 'locked'; + SettingsListener.observe('lockscreen.locked', false, function(value) { + if (value) { + screenState = 'locked'; + } else { + screenState = 'unlocked'; + } + }); + + /* === WebActivity === */ + function handleActivity(activity) { + // Workaround here until the bug 787415 is fixed + // Gecko is sending an activity event in every multiple entry point + // instead only the one that the href match. + if (activity.source.name != 'dial') + return; + + currentActivity = activity; + + var number = activity.source.data.number; + var fillNumber = function actHandleDisplay() { + if (number) { + KeypadManager.updatePhoneNumber(number); + if (window.location.hash != '#keyboard-view') { + window.location.hash = '#keyboard-view'; + } + call(number); + } + } + + if (document.readyState == 'complete') { + fillNumber(); + } else { + window.addEventListener('localized', function loadWait() { + window.removeEventListener('localized', loadWait); + fillNumber(); + }); + } + + activity.postResult({ status: 'accepted' }); } -}); + window.navigator.mozSetMessageHandler('activity', handleActivity); -var CallHandler = { - call: function ch_call(number) { + /* === Incoming calls === */ + function incoming() { + if (callScreenDisplayed) + return; + + openCallScreen(); + } + window.navigator.mozSetMessageHandler('telephony-incoming', incoming); + + /* === Calls === */ + function call(number) { var settings = window.navigator.mozSettings, req; if (settings) { - // Once - // https://bugzilla.mozilla.org/show_bug.cgi?id=788561 - // lands, we should get rid of `getLock()` call below. - var settingsLock; - if (settings.createLock) { - settingsLock = settings.createLock(); - } else { - settingsLock = settings.getLock(); - } + var settingsLock = settings.createLock(); req = settingsLock.get('ril.radio.disabled'); req.addEventListener('success', function onsuccess() { var status = req.result['ril.radio.disabled']; if (!status) { - this.startDial(number); + startDial(number); } else { - CustomDialog.show( - _('callFlightModeTitle'), - _('callFlightModeBody'), - { - title: _('callFlightModeBtnOk'), - callback: function() { - CustomDialog.hide(); - - if (CallHandler.activityCurrent) { - CallHandler.activityCurrent.postError('canceled'); - CallHandler.activityCurrent = null; - } - } - } - ); + handleFlightMode(); } - }.bind(this)); + }); } else { - this.startDial(number); + startDial(number); } - }, - - _isUSSD: function ch_isUSSD(number) { - var ussdChars = ['*', '#']; - - var relevantNumbers = []; - relevantNumbers.push(number.slice(0, 1)); - relevantNumbers.push(number.slice(-1)); - - return relevantNumbers.every(function ussdTest(number) { - return ussdChars.indexOf(number) !== -1; - }); - }, + } - startDial: function ch_startDial(number) { - if (this._isUSSD(number)) { + function startDial(number) { + if (isUSSD(number)) { UssdManager.send(number); } else { var sanitizedNumber = number.replace(/-/g, ''); - var telephony = window.navigator.mozTelephony; if (telephony) { - var call; - if (navigator.mozMobileConnection && - navigator.mozMobileConnection.voice && - navigator.mozMobileConnection.voice.emergencyCallsOnly) { - call = telephony.dialEmergency(sanitizedNumber); - } else { - call = telephony.dial(sanitizedNumber); - } + var call = telephony.dial(sanitizedNumber); if (call) { var cb = function clearPhoneView() { @@ -85,14 +95,46 @@ var CallHandler = { }; call.onconnected = cb; call.ondisconnected = cb; + call.onerror = handleError; - call.onerror = this.callError; + if (!callScreenDisplayed) + openCallScreen(); } } } - }, + } + + function isUSSD(number) { + var ussdChars = ['*', '#']; + + var relevantNumbers = []; + relevantNumbers.push(number.slice(0, 1)); + relevantNumbers.push(number.slice(-1)); + + return relevantNumbers.every(function ussdTest(number) { + return ussdChars.indexOf(number) !== -1; + }); + } + + function handleFlightMode() { + CustomDialog.show( + _('callFlightModeTitle'), + _('callFlightModeBody'), + { + title: _('callFlightModeBtnOk'), + callback: function() { + CustomDialog.hide(); - callError: function callError(event) { + if (currentActivity) { + currentActivity.postError('canceled'); + currentActivity = null; + } + } + } + ); + } + + function handleError(event) { var erName = event.call.error.name, emgcyDialogBody, errorRecognized = false; @@ -117,7 +159,33 @@ var CallHandler = { ); } } -}; + + /* === Attention Screen === */ + function openCallScreen() { + if (callScreenDisplayed) + return; + + callScreenDisplayed = true; + + var host = document.location.host; + var protocol = document.location.protocol; + var urlBase = protocol + '//' + host + '/dialer/oncall.html'; + window.open(urlBase + '#' + screenState, + 'call_screen', 'attention'); + } + + // We use a simple postMessage protocol to know when the call screen is closed + function handleMessage(evt) { + if (evt.data == 'closing') { + callScreenDisplayed = false; + } + } + window.addEventListener('message', handleMessage); + + return { + call: call + }; +})(); var NavbarManager = { init: function nm_init() { @@ -172,38 +240,6 @@ window.addEventListener('localized', function startup(evt) { document.body.classList.remove('hidden'); }); -window.navigator.mozSetMessageHandler('activity', function actHandle(activity) { - // Workaround here until the bug 787415 is fixed - // Gecko is sending an activity event in every multiple entry point - // instead only the one that the href match. - if (activity.source.name != 'dial') - return; - - CallHandler.activityCurrent = activity; - - var number = activity.source.data.number; - var fillNumber = function actHandleDisplay() { - if (number) { - KeypadManager.updatePhoneNumber(number); - if (window.location.hash != '#keyboard-view') { - window.location.hash = '#keyboard-view'; - } - CallHandler.call(number); - } - } - - if (document.readyState == 'complete') { - fillNumber(); - } else { - window.addEventListener('localized', function loadWait() { - window.removeEventListener('localized', loadWait); - fillNumber(); - }); - } - - activity.postResult({ status: 'accepted' }); -}); - // Listening to the keyboard being shown // Waiting for issue 787444 being fixed window.onresize = function(e) { @@ -214,3 +250,13 @@ window.onresize = function(e) { } }; +// Keeping the call history up to date +document.addEventListener('mozvisibilitychange', function visibility(e) { + if (!document.mozHidden) { + RecentsDBManager.init(function dbReady() { + RecentsDBManager.get(function(recents) { + Recents.render(recents); + }); + }); + } +}); diff --git a/apps/communications/dialer/js/oncall.js b/apps/communications/dialer/js/oncall.js index 31a58ca87aa3..7ec371b4a4c1 100644 --- a/apps/communications/dialer/js/oncall.js +++ b/apps/communications/dialer/js/oncall.js @@ -7,6 +7,7 @@ var CallScreen = { views: document.getElementById('views'), calls: document.getElementById('calls'), + get activeCall() { delete this.activeCall; return this.activeCall = this.calls.querySelector(':not(.held)'); @@ -38,17 +39,17 @@ var CallScreen = { this.answerButton.addEventListener('mouseup', OnCallHandler.answer.bind(OnCallHandler)); this.rejectButton.addEventListener('mouseup', - OnCallHandler.end.bind(OnCallHandler)); + OnCallHandler.end); this.incomingAnswer.addEventListener('mouseup', - OnCallHandler.holdAndAnswer.bind(OnCallHandler)); + OnCallHandler.holdAndAnswer); this.incomingEnd.addEventListener('mouseup', - OnCallHandler.endAndAnswer.bind(OnCallHandler)); + OnCallHandler.endAndAnswer); this.incomingIgnore.addEventListener('mouseup', - OnCallHandler.ignore.bind(OnCallHandler)); + OnCallHandler.ignore); this.calls.addEventListener('click', - OnCallHandler.toggleCalls.bind(OnCallHandler)); + OnCallHandler.toggleCalls); }, @@ -149,154 +150,215 @@ var CallScreen = { } }; -var OnCallHandler = { - CALLS_LIMIT: 2, // Changing this will probably require some markup changes +var OnCallHandler = (function onCallHandler() { + // Changing this will probably require markup changes + var CALLS_LIMIT = 2; + var _ = navigator.mozL10n.get; + + var handledCalls = []; + var telephony = window.navigator.mozTelephony; + + var displayed = false; + var closing = false; - handledCalls: [], - _telephony: window.navigator.mozTelephony, + /* === Ringtone player === */ + var ringtonePlayer = new Audio(); + ringtonePlayer.loop = true; - _displayed: false, - _closing: false, + /* === Settings === */ + var activePhoneSound = true; + SettingsListener.observe('phone.ring.incoming', true, function(value) { + activePhoneSound = !!value; + }); - setup: function och_setup() { + var selectedPhoneSound = ''; + SettingsListener.observe('dialer.ringtone', 'classic.ogg', function(value) { + selectedPhoneSound = 'style/ringtones/' + value; + ringtonePlayer.src = selectedPhoneSound; + }); + + var activateVibration = true; + SettingsListener.observe('phone.vibration.incoming', false, function(value) { + activateVibration = !!value; + }); + + /* === Setup === */ + function setup() { // Animating the screen in the viewport. - this.toggleScreen(); + toggleScreen(); ProximityHandler.enable(); - var telephony = this._telephony; if (telephony) { // Somehow the muted property appears to true after initialization. // Set it to false. telephony.muted = false; - var self = this; - var callsChanged = function och_callsChanged(evt) { - // Adding any new calls to handledCalls - telephony.calls.forEach(function callIterator(call) { - if (call.state == 'incoming' || call.state == 'dialing') { - var alreadyAdded = self.handledCalls.some(function hcIterator(hc) { - return (hc.call == call); - }); - - if (!alreadyAdded) { - self._addCall(call); - } - } - }); + // Needs to be called at least once + onCallsChanged(); + telephony.oncallschanged = onCallsChanged; - // Removing any ended calls to handledCalls - self.handledCalls.forEach(function handledCallIterator(hc, index) { - var stillHere = telephony.calls.some(function hcIterator(call) { - return (call == hc.call); - }); + // If the call was ended before we got here we can close + // right away. + if (handledCalls.length === 0) { + exitCallScreen(false); + } + } + } - if (!stillHere) { - self._removeCall(index); - return; - } + /* === Handled calls === */ + function onCallsChanged() { + // Adding any new calls to handledCalls + telephony.calls.forEach(function callIterator(call) { + if (call.state == 'incoming' || call.state == 'dialing') { + var alreadyAdded = handledCalls.some(function hcIterator(hc) { + return (hc.call == call); }); - // Letting the layout know how many calls we're handling - CallScreen.calls.dataset.count = self.handledCalls.length; - }; + if (!alreadyAdded) { + addCall(call); + } + } + }); - // Needs to be called at least once - callsChanged(); - telephony.oncallschanged = callsChanged; + // Removing any ended calls to handledCalls + handledCalls.forEach(function handledCallIterator(hc, index) { + var stillHere = telephony.calls.some(function hcIterator(call) { + return (call == hc.call); + }); - // If the call was ended before we got here we can close - // right away. - if (this.handledCalls.length === 0) { - this._close(false); + if (!stillHere) { + removeCall(index); + return; } - } - }, + }); - answer: function ch_answer() { - // We should always have only 1 call here - if (!this.handledCalls.length) + // Letting the layout know how many calls we're handling + CallScreen.calls.dataset.count = handledCalls.length; + } + + function addCall(call) { + // Once we already have 1 call, we only care about incomings + if (handledCalls.length && (call.state != 'incoming')) return; - this.handledCalls[0].call.answer(); - CallScreen.render('connected'); - }, + // No more room + if (handledCalls.length >= CALLS_LIMIT) { + call.hangUp(); + return; + } + + var node = CallScreen.calls.children[handledCalls.length]; + var hc = new HandledCall(call, node); + handledCalls.push(hc); - holdAndAnswer: function och_holdAndAnswer() { - var lastCallIndex = this.handledCalls.length - 1; + // This is the initial incoming call, need to ring ! + if (call.state === 'incoming' && handledCalls.length === 1) { + handleFirstIncoming(call); + } - this._telephony.active.hold(); - this.handledCalls[lastCallIndex].call.answer(); + if (handledCalls.length > 1) { + // signaling the user of the new call + navigator.vibrate([100, 100, 100]); - CallScreen.hideIncoming(); - }, + var number = (call.number.length ? call.number : _('unknown')); + Contacts.findByNumber(number, function lookupContact(contact) { + if (contact && contact.name) { + CallScreen.incomingNumber.textContent = contact.name; + return; + } - endAndAnswer: function och_endAndAnswer() { - var callToEnd = this._telephony.active; - this.holdAndAnswer(); + CallScreen.incomingNumber.textContent = number; + }); - callToEnd.onheld = function hangUpAfterHold() { - callToEnd.hangUp(); - }; + CallScreen.showIncoming(); + } else { + if (window.location.hash === '#locked' && + (call.state == 'incoming')) { + CallScreen.render('incoming-locked'); + } else { + CallScreen.render(call.state); + } + } + } - CallScreen.hideIncoming(); - }, + function removeCall(index) { + handledCalls.splice(index, 1); - toggleCalls: function och_toggleCalls() { - if (this.handledCalls.length < 2) + if (handledCalls.length > 0) { + // Resuming the first remaining call + handledCalls[0].call.resume(); + CallScreen.hideIncoming(); return; + } - this._telephony.active.hold(); - }, + exitCallScreen(true); + } - ignore: function ch_ignore() { - var ignoreIndex = this.handledCalls.length - 1; - this.handledCalls[ignoreIndex].call.hangUp(); + function handleFirstIncoming(call) { + var screenLock = navigator.requestWakeLock('screen'); - CallScreen.hideIncoming(); - }, - - end: function ch_end() { - // If there is an active call we end this one - if (this._telephony.active) { - this._telephony.active.hangUp(); - return; + var vibrateInterval = 0; + if (activateVibration) { + vibrateInterval = window.setInterval(function vibrate() { + if ('vibrate' in navigator) { + navigator.vibrate([200]); + } + }, 600); } - // If not we're rejecting the last incoming call - if (!this.handledCalls.length) { - this.toggleScreen(); - return; + if (activePhoneSound && selectedPhoneSound) { + ringtonePlayer.play(); } - var lastCallIndex = this.handledCalls.length - 1; - this.handledCalls[lastCallIndex].call.hangUp(); - }, + call.addEventListener('statechange', function callStateChange() { + call.removeEventListener('statechange', callStateChange); - unmute: function ch_unmute() { - this._telephony.muted = false; - }, + ringtonePlayer.pause(); + window.clearInterval(vibrateInterval); - toggleMute: function ch_toggleMute() { - this._telephony.muted = !this._telephony.muted; - }, + if (screenLock) { + screenLock.unlock(); + screenLock = null; + } - turnSpeakerOff: function ch_turnSpeakeroff() { - this._telephony.speakerEnabled = false; - }, + // The call wasn't picked up + if (call.state == 'disconnected') { + navigator.mozApps.getSelf().onsuccess = function getSelfCB(evt) { + var app = evt.target.result; - toggleSpeaker: function ch_toggleSpeaker() { - this._telephony.speakerEnabled = !this._telephony.speakerEnabled; - }, + var iconURL = NotificationHelper.getIconURI(app); + + var notiClick = function() { + // Asking to launch itself + app.launch('#recents-view'); + }; + + Contacts.findByNumber(call.number, function lookup(contact) { + var title = _('missedCall'); + var sender = call.number.length ? + call.number : _('unknown'); + + if (contact && contact.name) { + sender = contact.name; + } + + var body = _('from', {sender: sender}); + + NotificationHelper.send(title, body, iconURL, notiClick); + }); + }; + } + }); + } + + /* === Call Screen === */ + function toggleScreen() { + displayed = !displayed; - toggleScreen: function ch_toggleScreen() { CallScreen.screen.classList.remove('animate'); CallScreen.screen.classList.toggle('prerender'); - var displayed = this._displayed; - this._displayed = !this._displayed; - - var self = this; window.addEventListener('MozAfterPaint', function ch_finishAfterPaint() { window.removeEventListener('MozAfterPaint', ch_finishAfterPaint); @@ -309,90 +371,129 @@ var OnCallHandler = { CallScreen.screen.removeEventListener('transitionend', trWait); // We did animate the call screen off the viewport // now closing the window. - if (displayed) { - self.closeWindow(); + if (!displayed) { + closeWindow(); } }); }); }); - }, + } + + function exitCallScreen(animate) { + if (closing) + return; + + ProximityHandler.disable(); + + closing = true; + + if (animate) { + toggleScreen(); + } else { + closeWindow(); + } + } - closeWindow: function och_closeWindow() { + function closeWindow() { var origin = document.location.protocol + '//' + document.location.host; window.opener.postMessage('closing', origin); window.close(); - }, + } - _addCall: function och_addCall(call) { - // Once we already have 1 call, we only care about incomings - if (this.handledCalls.length && (call.state != 'incoming')) + /* === User Actions === */ + function answer() { + // We should always have only 1 call here + if (!handledCalls.length) return; - // No more room - if (this.handledCalls.length >= this.CALLS_LIMIT) { - call.hangUp(); - return; - } + handledCalls[0].call.answer(); + CallScreen.render('connected'); + } - var node = CallScreen.calls.children[this.handledCalls.length]; - var hc = new HandledCall(call, node); - this.handledCalls.push(hc); + function holdAndAnswer() { + var lastCallIndex = handledCalls.length - 1; - if (this.handledCalls.length > 1) { - // signaling the user of the new call - navigator.vibrate([100, 100, 100]); + telephony.active.hold(); + handledCalls[lastCallIndex].call.answer(); - var _ = navigator.mozL10n.get; - var number = (call.number.length ? call.number : _('unknown')); - Contacts.findByNumber(number, function lookupContact(contact) { - if (contact && contact.name) { - CallScreen.incomingNumber.textContent = contact.name; - return; - } + CallScreen.hideIncoming(); + } - CallScreen.incomingNumber.textContent = number; - }); + function endAndAnswer() { + var callToEnd = telephony.active; + holdAndAnswer(); - CallScreen.showIncoming(); - } else { - if (window.location.hash.split('?')[1] === 'locked' && - (call.state == 'incoming')) { - CallScreen.render('incoming-locked'); - } else { - CallScreen.render(call.state); - } - } - }, + callToEnd.onheld = function hangUpAfterHold() { + callToEnd.hangUp(); + }; - _removeCall: function och_removeCall(index) { - this.handledCalls.splice(index, 1); + CallScreen.hideIncoming(); + } - if (this.handledCalls.length > 0) { - // Resuming the first remaining call - this.handledCalls[0].call.resume(); - CallScreen.hideIncoming(); + function toggleCalls() { + if (handledCalls.length < 2) return; - } - this._close(true); - }, + telephony.active.hold(); + } - _close: function och_close(animate) { - if (this._closing) - return; + function ignore() { + var ignoreIndex = handledCalls.length - 1; + handledCalls[ignoreIndex].call.hangUp(); - ProximityHandler.disable(); + CallScreen.hideIncoming(); + } - this._closing = true; + function end() { + // If there is an active call we end this one + if (telephony.active) { + telephony.active.hangUp(); + return; + } - if (animate) { - this.toggleScreen(); - } else { - this.closeWindow(); + // If not we're rejecting the last incoming call + if (!handledCalls.length) { + toggleScreen(); + return; } + + var lastCallIndex = handledCalls.length - 1; + handledCalls[lastCallIndex].call.hangUp(); } -}; + + function unmute() { + telephony.muted = false; + } + + function turnSpeakerOff() { + telephony.speakerEnabled = false; + } + + function toggleMute() { + telephony.muted = !telephony.muted; + } + + function toggleSpeaker() { + telephony.speakerEnabled = !telephony.speakerEnabled; + } + + return { + setup: setup, + + answer: answer, + holdAndAnswer: holdAndAnswer, + endAndAnswer: endAndAnswer, + toggleCalls: toggleCalls, + ignore: ignore, + end: end, + + toggleMute: toggleMute, + toggleSpeaker: toggleSpeaker, + unmute: unmute, + turnSpeakerOff: turnSpeakerOff + }; +})(); window.addEventListener('localized', function callSetup(evt) { window.removeEventListener('localized', callSetup); diff --git a/apps/communications/dialer/oncall.html b/apps/communications/dialer/oncall.html index de7e6335bdb3..ad1b5bda939a 100644 --- a/apps/communications/dialer/oncall.html +++ b/apps/communications/dialer/oncall.html @@ -10,6 +10,7 @@ + diff --git a/apps/communications/manifest.webapp b/apps/communications/manifest.webapp index d58227597c0d..1bab9d70f792 100644 --- a/apps/communications/manifest.webapp +++ b/apps/communications/manifest.webapp @@ -29,7 +29,6 @@ "voicemail", "contacts", "mobileconnection", - "background", "attention", "settings" ], @@ -37,7 +36,6 @@ "120": "/style/icons/Dialer.png", "60": "/style/icons/60/Dialer.png" }, - "background_page": "/dialer/background.html", "orientation": "portrait-primary", "activities": { "pick": { @@ -63,5 +61,8 @@ "href": "/dialer/index.html", "disposition": "window" } - } + }, + "messages": [ + { "telephony-incoming": "/dialer/index.html" } + ] } diff --git a/apps/system/emergency-call/index.html b/apps/system/emergency-call/index.html index 63308f249a30..c82d2183342a 100644 --- a/apps/system/emergency-call/index.html +++ b/apps/system/emergency-call/index.html @@ -6,8 +6,12 @@ Emergency Call Dialer - + + + + + @@ -144,5 +148,51 @@ +
+
+
+
+
+
+
+
+ Emergency call +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ +
+
+
+
+
+
+
+
+
+
diff --git a/apps/system/emergency-call/js/dialer.js b/apps/system/emergency-call/js/dialer.js index fd765a485e68..ff930092b372 100644 --- a/apps/system/emergency-call/js/dialer.js +++ b/apps/system/emergency-call/js/dialer.js @@ -1,23 +1,80 @@ 'use strict'; var CallHandler = { + _call: null, + _telephony: window.navigator.mozTelephony, + call: function ch_call(number) { var sanitizedNumber = number.replace(/-/g, ''); - var telephony = window.navigator.mozTelephony; + var telephony = this._telephony; if (telephony) { - var call = telephony.dialEmergency(sanitizedNumber); + this._call = telephony.dialEmergency(sanitizedNumber); + var call = this._call; if (call) { var cb = function clearPhoneView() { KeypadManager.updatePhoneNumber(''); }; call.onconnected = cb; - call.ondisconnected = cb; + + call.ondisconnected = function callEnded() { + cb(); + CallScreen.hide(); + }; + + CallScreen.number = call.number; + CallScreen.show(); } } + }, + + end: function ch_end() { + if (!this._call) { + CallScreen.hide(); + return; + } + + this._call.hangUp(); + this._call = null; + }, + + toggleSpeaker: function ch_toggleSpeaker() { + this._telephony.speakerEnabled = !this._telephony.speakerEnabled; + } +}; + +var CallScreen = { + screen: document.getElementById('call-screen'), + numberView: document.getElementById('emergency-number'), + + hangUpButton: document.getElementById('callbar-hang-up'), + speakerButton: document.getElementById('speaker'), + + set number(value) { + this.numberView.textContent = value; + }, + + init: function cs_init() { + this.hangUpButton.addEventListener('mouseup', + CallHandler.end.bind(CallHandler)); + this.speakerButton.addEventListener('click', this.toggleSpeaker.bind(this)); + }, + + show: function cs_show() { + this.screen.classList.add('displayed'); + }, + + hide: function cs_hide() { + this.screen.classList.remove('displayed'); + }, + + toggleSpeaker: function cs_toggleSpeaker() { + this.speakerButton.classList.toggle('speak'); + CallHandler.toggleSpeaker(); } }; window.addEventListener('load', function onload() { window.removeEventListener('load', onload); KeypadManager.init(); + CallScreen.init(); }); diff --git a/apps/system/emergency-call/style/dialer.css b/apps/system/emergency-call/style/dialer.css index 61a19c12a2a7..fc5210649113 100644 --- a/apps/system/emergency-call/style/dialer.css +++ b/apps/system/emergency-call/style/dialer.css @@ -84,3 +84,167 @@ html * { body.hidden *[data-l10n-id] { visibility: hidden; } + +/* Call screen */ +#call-screen { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + margin: 0; + border: 0; + border-radius: 10px; + background: black; + -moz-transform: translateY(-100%); + z-index: 100; + + -moz-transition: -moz-transform 0.5s ease; +} + +#call-screen.displayed { + -moz-transform: translateY(0); +} + +#main-container { + position: relative; + height: 100%; + background: transparent; +} + +#actions-container { + position: absolute; + bottom: 0; + width: 100%; + height: 15.5rem; +} + +#call-options { + height:9.5rem; +} + +#co-advanced { + opacity: 1.0; + height: 9.5rem; +} + +.co-advanced-option { + background: rgba(0,0,0,.8); + height: 9.5rem; + width: 100%; + border: 0; + border-top: 1px solid #3A3A3A; + border-bottom: 1px solid #3A3A3A; + border-right: 1px solid #3A3A3A; +} + +#co-advanced span.grid-cell:last-child .co-advanced-option { + border-right: 0px; +} + +#speaker span { + display:inline-block; + background-color: #DDD; + background:url('images/ActionIcon_40x40_bluetooth.png') ; + background-size: 4rem 4rem; + width:4rem; + height:4rem; + opacity: 1.0; +} + +#speaker.speak > span { + background:url('images/ActionIcon_40x40_bluetooth_active.png'); +} + +#callbar { + background:rgba(0,0,0,.8); + opacity: 1.0; +} + +#callbar-hang-up { + float: left; + height: 6.5rem; + width: 100%; +} + +.callbar-button { + height: 4rem; + border:0; + border-radius:.3rem; + display: block; +} + +#callbar-hang-up-action { + background: -moz-linear-gradient(top, #ff0000 1%, #ce0000 100%); + opacity: 1.0; + margin: 1rem .5rem 1.5rem 1.5rem; +} + +#callbar-hang-up.full-space > #callbar-hang-up-action { + margin: 1rem 1.5rem 1.5rem 1.5rem; +} + +#callbar-hang-up-action > div { + margin: 0 auto; + background-image: url('images/ActionIcon_40x40_hangup.png'); + background-repeat: no-repeat; + background-size: 4rem 4rem; + background-position: center; + width: 4rem; + height: 4rem; +} + +#calls { + position: absolute; + top: 0; + width: 100%; + height: 22rem; + + z-index: 500; +} + +#calls > section { + position: relative; + height: 9rem; + + font-size: 1.8em; + line-height: 7rem; + background-color: #01c5ed; + + transition: opacity 0.3s linear; + opacity: 1; +} + +#calls > section div { + padding-left: 2rem; + padding-right: 1.5rem; +} + +#calls > section .number { + height: 4rem; + padding: 2rem 2rem 0 2rem; + background: #01c5ed; + font-size: 1.6em; + line-height: 4rem; + color: black; +} + +#calls > section .additionalContactInfo { + height: 2rem; + padding: 0 2rem 2rem 2rem; + background: #01c5ed; + font-size: 1.4rem; + line-height: 2rem; + color: white; +} + +#calls > section .duration { + position: absolute; + top: 12rem; + left: 0; + height: 8rem; + padding: 2rem; + font-size: 2.6em; + font-weight: 300; + line-height: 8rem; +} diff --git a/apps/system/emergency-call/style/images/ActionIcon_40x40_bluetooth.png b/apps/system/emergency-call/style/images/ActionIcon_40x40_bluetooth.png new file mode 100644 index 0000000000000000000000000000000000000000..b774edf5eb3ff32e4414334cea928392491f844f GIT binary patch literal 2124 zcmbVNc~nzp77v?3Pzns97Qr-t>`7h-grp#51A-$a`;;_ zy1`Hw%pz47&r-4&Ylu9l7{xKkpj2WRgoeRF!&Nd4FCA1OxS&8N2}4e_T|^>;{4iuf z5Cg-IQNUDTRE`{s%VEaza?*JOJ~DhIB2-0$6o^432cZ&+BnqM`4EaGX5n7v$(MZGx z5oLN9@}pBMMht=?m4k>N6efU&2?h|sI23@x5O4&41Qr8e&;S;V!3O{sVi2B)0T8nv z60#=erx0VQ5wo_ST^KS|sgx1X=XGek)Z(;1}zqw;`$)1 zP{x9Py75_QMf_G7h>isn(o8uI%14U(92ny6uML?5A#aFldGYx1SAq#94)vn|E(~UwL#LAB zRS#aU7*Q_5CBa6&I&IC^bmY%Y>wbCAKl0P@CRUPzL*9WAbz2!&Q|8tc6qA*^&j0tm zq>>yztGzqd7rEtlr-tDUk_S#yaNq4^6()HU)!$<~w)K{;oKUV<;}zJwhkkT^xT^ez z*SUgiuiC>0U)S%Bs9pNw?idtAEE9CEZGf51L=jXQmxqUbyH;yS+EwcLVc<*T2`|67xCL>zVX3@M3xG zs@6kTUnfH^@~DC2WGMAZDE=pW(V7PSGScrrwEpXkFY-4cy9#4Tmy7~-jELGFuIuRu zt?f_qq^Eg0J)KtpYbnHd+P>U4B(08nu^hg$T(8$VzpFNSKeT_U84%sO;cI!OGJI=t%H#0{|FY=7r}II}WaH=ihq^03~7 zzum19fZ$G9z+-V>U?5NR$lGNk-UhBX(A3;a+Evxi(BO6V?p<>6{g6T1bNk{P)Q4&{ znrSzYG<+$kS#7zCQ$YW@t}cZum%sAbXYiD~cR`M3wYip-mS)YI-({Sxar8KT@??w0 z*z@OZoyX>BVBw=LRpVsNjf?AN#5R)&KeDex35uF7k4+T=J=!aY^sKCDm(3e6M&>(x zjiVugaJIW(igmhlEImD)I=<@{!f%!($FBhL+}vE_)2X);mxi0Ju`!3PPWv`mxu)5f z|GN21MOj(d1Q~D{IIGcYAy(Z=mQ5Uc4pF9o=RM>&gz8EvD=QW82?>KYy1Q$lQ(Q7> zv?~@52agE+w_bemmYJ+EHc$@Nu%}>6O*<;MS@=H1v^Xppg+=)%f%QK2=dsRS@nnI!MO-f37e7yxD z_4D?=ozZ*evYVl2s)M4RuN~OE-tdLUc}wSa-8x;_0-*Vu$Y@1D#x*$m`Lk!OqBDsT zwQr;QcBq6xpG#BcjYk_?ZZP`p-)}Jt-SqHxY`wU8`NY`Rq?&(oe7teBu%M)Kbkd=9 zaQDNJ5v03bzfq$a~XU z20TjRZdwA>U z<=5q>mwmkx%}I9(@b%@=)kFJTU0vN*l+^FAJ+We-vr0euiulaTSUo@c!JAXjc6N4+ zU+u4G0^j~^IC0e$+MDT8xZ!QJKgqth$`6IAi&|!}Pw^Yy^?h5th-hDs#holav?8_8_-A3RxN+5i9m literal 0 HcmV?d00001 diff --git a/apps/system/emergency-call/style/images/ActionIcon_40x40_bluetooth_active.png b/apps/system/emergency-call/style/images/ActionIcon_40x40_bluetooth_active.png new file mode 100644 index 0000000000000000000000000000000000000000..a623e312e1979c78ac2840ebc2dbbdeda4603805 GIT binary patch literal 2134 zcmaJ?dpK0<8XrSD5eaRPG!0vFnX7RbmzawTjmvP#W#;WwZ8BDp5O2HzTf-)o@eC- z1?<+-G1EbzP;8gTnIpU^T8MZ!;)|X00-dm zlMi$P?kJQdRumcrhq3oid7uQxRby}pi40+*Q0}`FGA>UHz?c|7Ad-4ur<+=^7!ltC zyN|*quw`^WDDq8#fRL1cP+p3d=gPIq zK0;uz2ln@(!q`C=ItT$63Xb5wBRCN-PDC7$?C9+5Y>y!khy*-=geQ_5h|W|piAo?~ zK0R0@8^n*Lau`0Jav_liRtUo~DjuJdl!Qwn<3LD&C%U@2sx?R?2L$0DPnN=5g@aUX zxuU=Tw`VNfmvWf*!0 z1;gg@L{fG95zl5*SyDO7mGS@D8YQZGF7yCEwokjK5_Z0 z*Fs;Fi${vVs|WjEgI+m8+@s!pwk;BTHa;Ll+zuhOwtw@~1%=YO#bS7eDjvKDi`-)l z7?*b8B8wW{-}X6YZKb?3_;+H}_WjAi%m((o7)igDG6?54rE1r*uc(HowAbH;HY>XuY~2;L9BA8HrUc$=lDHDz z`H?MCnYM!@)NYN2MLbsUiK(hsH?6>I1&2Aclas|7%fEPc z${FLta*c>+Rk!vvWs6zvBu*oa*sFb>-I|GZY*W>B`(YOzTx!l5&nV|uZ??`&s#|B$ zc}}9_&!%lKM)}z;vRY{P?4^fZ@}F-{L-S;v8%B=ZLfKHpTa$+A$D<~1FiR}GAZ?qF zIrOG*1*21*9+K`9@pv*ZT-rbpH+n^9D-3g+aRmdKTACVCJFhBT+|_l7*b1$9FTL{p z6@m55hl-miV{?k2_TZ*h3zes~pNL315S%zybZ{(d=bL>yzIBRE{>^dzu36Ntwu{{Q z`mL!6`+P6=6+8#-D%R?U&(Q2m^AqQPTqLLa3qU~BJJu%LNE1z-31<2hrk&_LYkOSm zxc89EuyxIhfxPePjk@|KifTT;; zEB}TA7Khhe{hkoK)+N9&%XRba-Fh(E*1MfwTl?VtaLCDf0odgHwu_Y$CRwDB*Yg`s zK7L|)y*1ogS1`FVGx7eq_MyD%<1Z#UQwFXy-OL#lUtCH8I~H&~h1#7TwmsYxU@-Pe zZA`RXdL75_`8eZAG;l!DfBNRswX+?!4q7%GekfaFzDoAli+*-mVPUSCxbZ_i#%`~u z*c`l^Hm)r2JDrt!B&LMC%r_a**^nlv_vJO||Gzm!hvEd0A?kJWE>)5f>c zZ*WWBJ#9a;wq^TxRQ$Vcqkdqp+vU`m(F=_x6HSLb-Qe|9|4|-{Jd@=dD)UAK- zbodX>>;F`k-B}e%ON zhf|b|barSF!7xwo_EC*|qUD^wZVCBx?Z%qmvTn0#no4rShqYx>FlD_h82eB}1(BW#(x0uDRcDz literal 0 HcmV?d00001 diff --git a/apps/system/emergency-call/style/images/ActionIcon_40x40_hangup.png b/apps/system/emergency-call/style/images/ActionIcon_40x40_hangup.png new file mode 100644 index 0000000000000000000000000000000000000000..d3fdc88021f70ebb7396fb2d1df8c2c3ae99f75b GIT binary patch literal 1707 zcmbVNdrT8|9IxOgh{m8q9xAz=hT(wT!$Kcv!9Jyo0;!D>g9%6PC>7c(cPA}X7gt{} zL=+kF2&hpfNbt=zM1o*s8bg9OL7YGpoFnLrqT3jXyYkTeVf^0h_nTiq za^l(r^MdDbIGhEVIHiuA!`#2O7d!5o{K?EtL5wPeSx06tHjE-TGMr2&0F4l1Edp1lSK+XZ*Bzv6D|ce zL}_8IRY7E$;v5vQ&XK4$II;{P9E^*Y0zhE|h7c5j1(66WjuMDr1ep0i)*6Lp zh;>T!j4gI21v44ODuy7N&Bn8>=8=>ULPR1F1fvj&MzRu-be@I5?2#6F#jFM;K^rKO zl`)YPz^xHWC$}(Cko9yr1hZAEeXrO;&k)5@2H7zygz#Xm8SK1 zRszxyG`WQ`u=&VXF$-q7`?MjqAnT1di88TC!LpU4VT+ltFdC&4WN&!52^R}hA{Bxl zA{0j9Xd!|KQB)>Z$pk_~CFILc(X5V-Vfg}q09B$2xk@2J5EUX*2!!mYmI+i*d?jB# zi`7_Y2D2E5S-U3I?hID`Nvv2w5g0>KdXmhZt$^fAk|F6#(h4ZnMFU}4%wV#(4_3Jo zG##&!piH?0uBJ#cFvYOg^brqaXcUa7

)6A##~oh$!Uli`6P{28;h6)*#jy$Xy=) zDVNzJwg%nH_r=d{-nS27VS9#RnxK|9kI7QF^S;)K`QssfUhEVQ1k8;E;_r*|K^yUX)Jh&OP( zV^6W%*W7oq)#T;eRlK0+JhJ-c;tVXNX8V)szKGQNyOqLQs;Ha}-^I8y;eZb+3%xP7 z!qwH@7|!K#<0n!*F0SE>xt6`HNnM)R;-$OvwfCY|V&Cq!UUxS)8hm-qDwo&e_EkG| zbB?S!a&-^brapdq=}E5Z^YY1C_2t~NZA)vO-0}Qu^tEGaMZ4?I*!U(JaP-cI?(N)y zdo)~!ue<~ekBvhW389TmP2-A^6W@n@OY9%o=mg67!9|-ftW6{ke378lHu)`YmTP>j z?7)wXbxuxBMr1mB!l_6D#0Vt~oIlVvFffpea&rpQ z$H%I@|9JN7;I_hjmm8I!-wV6sY;wOx>+R>snz&bvmeY}&!u)Fji#o2>#-tP(d51?I z7o;_;FYMAH=UmT{a+~`LZ{j-T#7m)11{}!$J^c8_lkJ{g)#)9hR$)lp$Z&gYn_q+f zaDEE$U;|5xLpf2h;a8>`#%7oDF{R{VA zbM}sIQv6*#bmQ}PXn1&dQg3f>Yl&y@SllN1lED1y?$XfS?@AS1K~?86Z8jaTq&e$i z-5j)%>#~XTtYFY;id-U00KX&YwNzbLz>oyr_qBp1Pk8jVe)jMxN&U7p|g^ An*aa+ literal 0 HcmV?d00001 diff --git a/apps/system/js/attention_screen.js b/apps/system/js/attention_screen.js index 5155bd26b1e7..6dcc26fd5de2 100644 --- a/apps/system/js/attention_screen.js +++ b/apps/system/js/attention_screen.js @@ -49,6 +49,13 @@ var AttentionScreen = { ListMenu.hide(); SleepMenu.hide(); + // We want the user attention, so we need to turn the screen on + // if it's off. The lockscreen will grab the focus when we do that + // so we need to do it before adding the new iframe to the dom + this._screenInitiallyDisabled = !ScreenManager.screenEnabled; + if (this._screenInitiallyDisabled) + ScreenManager.turnScreenOn(); + var attentionFrame = evt.detail.frameElement; attentionFrame.dataset.frameType = 'attention'; attentionFrame.dataset.frameName = evt.detail.name; @@ -57,13 +64,7 @@ var AttentionScreen = { this.attentionScreen.appendChild(attentionFrame); this.attentionScreen.classList.add('displayed'); - // We want the user attention, so we need to turn the screen on - // if it's off. - this._screenInitiallyDisabled = !ScreenManager.screenEnabled; - if (this._screenInitiallyDisabled) - ScreenManager.turnScreenOn(); - - // Ensuring the proper mozvisibility changed on the displayed app + // Ensuring the proper mozvisibility change on the displayed app var displayedOrigin = WindowManager.getDisplayedApp(); if (displayedOrigin) { var frame = WindowManager.getAppFrame(displayedOrigin); @@ -105,7 +106,6 @@ var AttentionScreen = { // We just removed the focused window leaving the system // without any focused window, let's fix this. window.focus(); - }, show: function as_show() { From 0e144215f5c2c4b9bee66ace3ac2ff7046521e1a Mon Sep 17 00:00:00 2001 From: Etienne Segonzac Date: Fri, 14 Sep 2012 16:43:52 +0200 Subject: [PATCH 2/2] Fixning an issue with a race condition between mozSetting and the dialer ringtone player. --- apps/communications/dialer/js/oncall.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/apps/communications/dialer/js/oncall.js b/apps/communications/dialer/js/oncall.js index 7ec371b4a4c1..83c8d02e5232 100644 --- a/apps/communications/dialer/js/oncall.js +++ b/apps/communications/dialer/js/oncall.js @@ -160,10 +160,7 @@ var OnCallHandler = (function onCallHandler() { var displayed = false; var closing = false; - - /* === Ringtone player === */ - var ringtonePlayer = new Audio(); - ringtonePlayer.loop = true; + var ringing = false; /* === Settings === */ var activePhoneSound = true; @@ -171,12 +168,21 @@ var OnCallHandler = (function onCallHandler() { activePhoneSound = !!value; }); - var selectedPhoneSound = ''; + var selectedPhoneSound = 'style/ringtones/classic.ogg'; SettingsListener.observe('dialer.ringtone', 'classic.ogg', function(value) { selectedPhoneSound = 'style/ringtones/' + value; + ringtonePlayer.pause(); ringtonePlayer.src = selectedPhoneSound; + + if (ringing) { + ringtonePlayer.play(); + } }); + var ringtonePlayer = new Audio(); + ringtonePlayer.src = selectedPhoneSound; + ringtonePlayer.loop = true; + var activateVibration = true; SettingsListener.observe('phone.vibration.incoming', false, function(value) { activateVibration = !!value; @@ -309,12 +315,15 @@ var OnCallHandler = (function onCallHandler() { if (activePhoneSound && selectedPhoneSound) { ringtonePlayer.play(); + ringing = true; } call.addEventListener('statechange', function callStateChange() { call.removeEventListener('statechange', callStateChange); ringtonePlayer.pause(); + ringing = false; + window.clearInterval(vibrateInterval); if (screenLock) {