Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
294 lines
12 KiB
JavaScript
Executable file
294 lines
12 KiB
JavaScript
Executable file
/* global BaseModule */
|
|
'use strict';
|
|
|
|
(function() {
|
|
// The results of audo channel competition.
|
|
var PLAY = true;
|
|
var PAUSE = false;
|
|
/**
|
|
* It is the table to get the result of
|
|
* the competition of audio channels.
|
|
*
|
|
* Get the result of the competition
|
|
* of normal and content audio channels with
|
|
* `AUDIO_CHANNEL_COMPETITION_RESULTS.normal.content`.
|
|
*/
|
|
var AUDIO_CHANNEL_COMPETITION_RESULTS = {
|
|
normal: {
|
|
normal: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
content: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
alarm: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
system: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
ringer: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
telephony: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
notification: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
publicnotification: { activeAudioChannel: PLAY, newAudioChannel: PLAY }
|
|
},
|
|
content: {
|
|
normal: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
content: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
alarm: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
system: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
ringer: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
telephony: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
notification: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
publicnotification: { activeAudioChannel: PLAY, newAudioChannel: PLAY }
|
|
},
|
|
alarm: {
|
|
normal: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
content: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
alarm: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
system: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
ringer: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
telephony: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
notification: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
publicnotification: { activeAudioChannel: PLAY, newAudioChannel: PLAY }
|
|
},
|
|
system: {
|
|
normal: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
content: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
alarm: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
system: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
ringer: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
telephony: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
notification: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
publicnotification: { activeAudioChannel: PLAY, newAudioChannel: PLAY }
|
|
},
|
|
ringer: {
|
|
normal: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
content: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
alarm: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
system: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
ringer: { activeAudioChannel: PAUSE, newAudioChannel: PLAY },
|
|
telephony: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
notification: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
publicnotification: { activeAudioChannel: PLAY, newAudioChannel: PLAY }
|
|
},
|
|
telephony: {
|
|
normal: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
content: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
alarm: { activeAudioChannel: PLAY, newAudioChannel: PAUSE },
|
|
system: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
ringer: { activeAudioChannel: PLAY, newAudioChannel: PAUSE },
|
|
notification: { activeAudioChannel: PLAY, newAudioChannel: PAUSE },
|
|
publicnotification: { activeAudioChannel: PLAY, newAudioChannel: PLAY }
|
|
},
|
|
notification: {
|
|
normal: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
content: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
alarm: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
system: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
ringer: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
telephony: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
notification: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
publicnotification: { activeAudioChannel: PLAY, newAudioChannel: PLAY }
|
|
},
|
|
publicnotification: {
|
|
normal: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
content: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
alarm: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
system: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
ringer: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
telephony: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
notification: { activeAudioChannel: PLAY, newAudioChannel: PLAY },
|
|
publicnotification: { activeAudioChannel: PLAY, newAudioChannel: PLAY }
|
|
}
|
|
};
|
|
|
|
/**
|
|
* AudioChannelPolicy provides policies to handle audio channels.
|
|
*/
|
|
var AudioChannelPolicy = function() {};
|
|
|
|
AudioChannelPolicy.SETTINGS = [
|
|
'vibration.enabled'
|
|
];
|
|
|
|
BaseModule.create(AudioChannelPolicy, {
|
|
name: 'AudioChannelPolicy',
|
|
DEBUG: false,
|
|
// The value of the vibration.enabled settings.
|
|
_isVibrateEnabled: true,
|
|
|
|
/**
|
|
* Get the policies of
|
|
* handling the new audio channel and active audio channels.
|
|
*
|
|
* @param {AudioChannelController} newAudioChannel
|
|
* A new audio channel you want to handle.
|
|
* @param {Map} activeAudioChannels
|
|
* Active audio channels playing noew.
|
|
* @param {Object} [options] Options.
|
|
* @param {Boolean} [options.isNewAudioChannelInBackground]
|
|
* Is the new audio channel in background.
|
|
*/
|
|
applyPolicy: function(newAudioChannel, activeAudioChannels, options) {
|
|
var newAudioChannelName = newAudioChannel.name;
|
|
// Deconflict the conflicted policies for the new audio channel.
|
|
// For example, we have a new audio channel `alarm` and
|
|
// two active audio channels `system` and `telephony`.
|
|
// `AUDIO_CHANNEL_COMPETITION_RESULTS.system.alarm` is `true`,
|
|
// but `AUDIO_CHANNEL_COMPETITION_RESULTS.telephony.alarm`
|
|
// is `false`.
|
|
// And we get conflict policies for the `alarm` audio channel.
|
|
// Once we get conflcts, we will take higher priority policy.
|
|
// `PAUSE` is higher than `PLAY`,
|
|
// and doing fade out is higher than not doing fade out.
|
|
var isAllowedToPlayForNewAudioChannel = [true];
|
|
var isNeededToFadeOutForNewAudioChannel = [false];
|
|
// The new audio channel will be allowed to play,
|
|
// if any other audio channel belonged to its app is already playing.
|
|
var isNewAudioChannelsAppPlaying = false;
|
|
activeAudioChannels.forEach((audioChannel) => {
|
|
if (audioChannel.app.instanceID === newAudioChannel.app.instanceID) {
|
|
isNewAudioChannelsAppPlaying = true;
|
|
}
|
|
});
|
|
!isNewAudioChannelsAppPlaying &&
|
|
activeAudioChannels.forEach((audioChannel) => {
|
|
var activeAudioChannelName = audioChannel.name;
|
|
var results = AUDIO_CHANNEL_COMPETITION_RESULTS
|
|
[activeAudioChannelName][newAudioChannelName];
|
|
var policy = {
|
|
isAllowedToPlay: results.activeAudioChannel
|
|
};
|
|
if (results.activeAudioChannel) {
|
|
policy.isNeededToFadeOut =
|
|
this._isNeededToFadeOutForActiveAudioChannel(
|
|
activeAudioChannelName, newAudioChannelName
|
|
);
|
|
}
|
|
if (!results.activeAudioChannel) {
|
|
policy.isNeededToVibrate = this._isVibrateEnabled &&
|
|
this._isNeededToVibrateForActiveAudioChannel(
|
|
activeAudioChannelName, newAudioChannelName
|
|
);
|
|
policy.isNeededToResumeWhenOtherEnds =
|
|
this._isNeededToResumeWhenOtherEndsForActiveAudioChannel(
|
|
activeAudioChannelName, newAudioChannelName
|
|
);
|
|
}
|
|
audioChannel.setPolicy(policy);
|
|
this.debug('Policy for ' + audioChannel.instanceID +
|
|
': ' + JSON.stringify(policy));
|
|
isAllowedToPlayForNewAudioChannel.push(results.newAudioChannel);
|
|
results.newAudioChannel && isNeededToFadeOutForNewAudioChannel.push(
|
|
this._isNeededToFadeOutForNewAudioChannel
|
|
(activeAudioChannelName, newAudioChannelName)
|
|
);
|
|
});
|
|
// Normal channel could not play in background.
|
|
if (newAudioChannelName === 'normal' &&
|
|
options && options.isNewAudioChannelInBackground) {
|
|
isAllowedToPlayForNewAudioChannel.push(false);
|
|
}
|
|
// Deconflict the policies.
|
|
isAllowedToPlayForNewAudioChannel =
|
|
isAllowedToPlayForNewAudioChannel.every(isAllowed => isAllowed);
|
|
isNeededToFadeOutForNewAudioChannel =
|
|
isNeededToFadeOutForNewAudioChannel.some(isNeeded => isNeeded);
|
|
var policy = {
|
|
isAllowedToPlay: isAllowedToPlayForNewAudioChannel
|
|
};
|
|
if (isAllowedToPlayForNewAudioChannel) {
|
|
policy.isNeededToFadeOut = isNeededToFadeOutForNewAudioChannel;
|
|
}
|
|
if (!isAllowedToPlayForNewAudioChannel) {
|
|
policy.isNeededToVibrate = this._isVibrateEnabled &&
|
|
!isAllowedToPlayForNewAudioChannel &&
|
|
// Don't vibrate for background normal audio channel.
|
|
newAudioChannelName !== 'normal';
|
|
}
|
|
newAudioChannel.setPolicy(policy);
|
|
this.debug('Policy for ' + newAudioChannel.instanceID +
|
|
': ' + JSON.stringify(policy));
|
|
},
|
|
|
|
/**
|
|
* Observer the value of vibration.enabled settings.
|
|
*
|
|
* @param {Boolean} value The value of the settings.
|
|
*/
|
|
'_observe_vibration.enabled': function(value) {
|
|
this._isVibrateEnabled = value;
|
|
},
|
|
|
|
/**
|
|
* Get the policy of fading out the new audio channel.
|
|
*
|
|
* @param {String} activeChannelName The active audio channel name.
|
|
* @param {String} newChannelName The new audio channel name.
|
|
* @return {Boolean}
|
|
*/
|
|
_isNeededToFadeOutForNewAudioChannel:
|
|
function(activeChannelName, newChannelName) {
|
|
var isNeeded = false;
|
|
if ((activeChannelName === 'notification' ||
|
|
activeChannelName === 'publicnotification') &&
|
|
(newChannelName === 'normal' ||
|
|
newChannelName === 'content')
|
|
)
|
|
{
|
|
isNeeded = true;
|
|
}
|
|
return isNeeded;
|
|
},
|
|
|
|
/**
|
|
* Get the policy of fading out the active audio channel.
|
|
*
|
|
* @param {String} activeChannelName The active audio channel name.
|
|
* @param {String} newChannelName The new audio channel name.
|
|
* @return {Boolean}
|
|
*/
|
|
_isNeededToFadeOutForActiveAudioChannel:
|
|
function(activeChannelName, newChannelName) {
|
|
var isNeeded = false;
|
|
if (((activeChannelName === 'normal' ||
|
|
activeChannelName === 'content') &&
|
|
(newChannelName === 'notification' ||
|
|
newChannelName === 'publicnotification')
|
|
) ||
|
|
(activeChannelName === 'alarm' &&
|
|
(newChannelName === 'ringer' ||
|
|
newChannelName === 'telephony')
|
|
)
|
|
)
|
|
{
|
|
isNeeded = true;
|
|
}
|
|
return isNeeded;
|
|
},
|
|
|
|
/**
|
|
* Get the policy of vibrating for the active audio channel.
|
|
*
|
|
* @param {String} activeChannelName The active audio channel name.
|
|
* @param {String} newChannelName The new audio channel name.
|
|
* @return {Boolean}
|
|
*/
|
|
_isNeededToVibrateForActiveAudioChannel:
|
|
function(activeChannelName, newChannelName) {
|
|
return activeChannelName === 'ringer' && newChannelName === 'ringer';
|
|
},
|
|
|
|
/**
|
|
* Get the policy of resuming the active audio channel
|
|
* when any other audio channel ends.
|
|
*
|
|
* @param {String} activeChannelName The active audio channel name.
|
|
* @param {String} newChannelName The new audio channel name.
|
|
* @return {Boolean}
|
|
*/
|
|
_isNeededToResumeWhenOtherEndsForActiveAudioChannel:
|
|
function(activeChannelName, newChannelName) {
|
|
var isNeeded = true;
|
|
if (activeChannelName === 'normal' ||
|
|
(activeChannelName === 'content' && newChannelName === 'normal') ||
|
|
(activeChannelName === 'alarm' && newChannelName === 'alarm')) {
|
|
isNeeded = false;
|
|
}
|
|
return isNeeded;
|
|
}
|
|
});
|
|
}());
|