Bug 817043 - mozaudiochanneltype attribute, r=sicking a=blocking-basecamp

This commit is contained in:
Andrea Marchesini 2012-12-04 11:46:07 -08:00
parent be8cc4e73e
commit d647339fe9
5 changed files with 114 additions and 75 deletions

View File

@ -570,6 +570,7 @@ GK_ATOM(mouseout, "mouseout")
GK_ATOM(mouseover, "mouseover")
GK_ATOM(mousethrough, "mousethrough")
GK_ATOM(mouseup, "mouseup")
GK_ATOM(mozaudiochannel, "mozaudiochannel")
GK_ATOM(mozasyncpanzoom, "mozasyncpanzoom")
GK_ATOM(mozfullscreenchange, "mozfullscreenchange")
GK_ATOM(mozfullscreenerror, "mozfullscreenerror")

View File

@ -605,6 +605,9 @@ protected:
return isPaused;
}
// Check the permissions for audiochannel.
bool CheckAudioChannelPermissions(const nsAString& aType);
// The current decoder. Load() has been called on this decoder.
// At most one of mDecoder and mSrcStream can be non-null.
nsRefPtr<MediaDecoder> mDecoder;

View File

@ -464,6 +464,7 @@ NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autoplay, autoplay)
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Loop, loop)
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, DefaultMuted, muted)
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMediaElement, Preload, preload, NULL)
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMediaElement, MozAudioChannelType, mozaudiochannel, "normal")
NS_IMETHODIMP
nsHTMLMediaElement::GetMozSrcObject(JSContext* aCtx, jsval *aParams)
@ -1934,9 +1935,9 @@ nsHTMLMediaElement::WakeLockBoolWrapper& nsHTMLMediaElement::WakeLockBoolWrapper
}
bool nsHTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
// Mappings from 'preload' attribute strings to an enumeration.
static const nsAttrValue::EnumTable kPreloadTable[] = {
@ -1947,6 +1948,17 @@ bool nsHTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
{ 0 }
};
// Mappings from 'mozaudiochannel' attribute strings to an enumeration.
static const nsAttrValue::EnumTable kMozAudioChannelAttributeTable[] = {
{ "normal", AUDIO_CHANNEL_NORMAL },
{ "content", AUDIO_CHANNEL_CONTENT },
{ "notification", AUDIO_CHANNEL_NOTIFICATION },
{ "alarm", AUDIO_CHANNEL_ALARM },
{ "telephony", AUDIO_CHANNEL_TELEPHONY },
{ "publicnotification", AUDIO_CHANNEL_PUBLICNOTIFICATION },
{ 0 }
};
if (aNamespaceID == kNameSpaceID_None) {
if (ParseImageAttribute(aAttribute, aValue, aResult)) {
return true;
@ -1958,12 +1970,52 @@ bool nsHTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
if (aAttribute == nsGkAtoms::preload) {
return aResult.ParseEnumValue(aValue, kPreloadTable, false);
}
if (aAttribute == nsGkAtoms::mozaudiochannel) {
bool parsed = aResult.ParseEnumValue(aValue, kMozAudioChannelAttributeTable, false,
&kMozAudioChannelAttributeTable[0]);
if (!parsed) {
return false;
}
AudioChannelType audioChannelType = static_cast<AudioChannelType>(aResult.GetEnumValue());
if (audioChannelType != mAudioChannelType &&
!mDecoder &&
CheckAudioChannelPermissions(aValue)) {
mAudioChannelType = audioChannelType;
}
return true;
}
}
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
aResult);
}
bool nsHTMLMediaElement::CheckAudioChannelPermissions(const nsAString& aString)
{
#ifdef MOZ_B2G
// Only normal channel doesn't need permission.
if (!aString.EqualsASCII("normal")) {
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (!permissionManager) {
return false;
}
uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
permissionManager->TestExactPermissionFromPrincipal(NodePrincipal(),
nsCString(NS_LITERAL_CSTRING("audio-channel-") + NS_ConvertUTF16toUTF8(aString)).get(), &perm);
if (perm != nsIPermissionManager::ALLOW_ACTION) {
return false;
}
}
#endif
return true;
}
void nsHTMLMediaElement::DoneCreatingElement()
{
if (HasAttr(kNameSpaceID_None, nsGkAtoms::muted))
@ -3439,78 +3491,6 @@ NS_IMETHODIMP nsHTMLMediaElement::SetMozPreservesPitch(bool aPreservesPitch)
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMediaElement::GetMozAudioChannelType(nsAString& aString)
{
switch (mAudioChannelType) {
case AUDIO_CHANNEL_NORMAL:
aString.AssignLiteral("normal");
break;
case AUDIO_CHANNEL_CONTENT:
aString.AssignLiteral("content");
break;
case AUDIO_CHANNEL_NOTIFICATION:
aString.AssignLiteral("notification");
break;
case AUDIO_CHANNEL_ALARM:
aString.AssignLiteral("alarm");
break;
case AUDIO_CHANNEL_TELEPHONY:
aString.AssignLiteral("telephony");
break;
case AUDIO_CHANNEL_PUBLICNOTIFICATION:
aString.AssignLiteral("publicnotification");
break;
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMediaElement::SetMozAudioChannelType(const nsAString& aString)
{
// Only normal channel doesn't need permission.
if (!aString.EqualsASCII("normal")) {
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (!permissionManager) {
return NS_ERROR_FAILURE;
}
uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
permissionManager->TestExactPermissionFromPrincipal(NodePrincipal(),
nsCString(NS_LITERAL_CSTRING("audio-channel-") + NS_ConvertUTF16toUTF8(aString)).get(), &perm);
if (perm != nsIPermissionManager::ALLOW_ACTION) {
return NS_ERROR_DOM_SECURITY_ERR;
}
}
// Then assign
AudioChannelType tmpType;
if (aString.EqualsASCII("normal")) {
tmpType = AUDIO_CHANNEL_NORMAL;
} else if (aString.EqualsASCII("content")) {
tmpType = AUDIO_CHANNEL_CONTENT;
} else if (aString.EqualsASCII("notification")) {
tmpType = AUDIO_CHANNEL_NOTIFICATION;
} else if (aString.EqualsASCII("alarm")) {
tmpType = AUDIO_CHANNEL_ALARM;
} else if (aString.EqualsASCII("telephony")) {
tmpType = AUDIO_CHANNEL_TELEPHONY;
} else if (aString.EqualsASCII("publicnotification")) {
tmpType = AUDIO_CHANNEL_PUBLICNOTIFICATION;
} else {
return NS_ERROR_FAILURE;
}
if (tmpType != mAudioChannelType && mDecoder) {
return NS_ERROR_FAILURE;
}
mAudioChannelType = tmpType;
return NS_OK;
}
ImageContainer* nsHTMLMediaElement::GetImageContainer()
{
VideoFrameContainer* container = GetVideoFrameContainer();

View File

@ -333,8 +333,10 @@ MOCHITEST_FILES = \
test_htmlcollection.html \
test_formelements.html \
test_rowscollection.html \
test_mozaudiochannel.html \
$(NULL)
MOCHITEST_BROWSER_FILES = \
browser_bug649778.js \
file_bug649778.html \

View File

@ -0,0 +1,53 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for mozaudiochannel</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
<audio id="audio1" />
<audio id="audio2" mozaudiochannel="foo" />
<audio id="audio3" mozaudiochannel="content" />
</div>
<pre id="test">
<script type="application/javascript">
var audio1 = document.getElementById("audio1");
ok(audio1, "Audio Element exists");
ok(audio1.mozAudioChannelType == "normal", "Default audio1 channel == 'normal'");
try {
audio1.mozAudioChannelType = "foo";
} catch(e) {}
ok(audio1.mozAudioChannelType == "normal", "Default audio1 channel == 'normal'");
audio1.mozAudioChannelType = "alarm";
ok(audio1.mozAudioChannelType == "alarm", "Default audio1 channel == 'alarm'");
var audio2 = document.getElementById("audio2");
ok(audio2, "Audio Element exists");
ok(audio2.mozAudioChannelType == "normal", "Default audio2 channel == 'normal'");
try {
audio2.mozAudioChannelType = "foo";
} catch(e) {}
ok(audio2.mozAudioChannelType == "normal", "Default audio2 channel == 'normal'");
audio2.mozAudioChannelType = "alarm";
ok(audio2.mozAudioChannelType == "alarm", "Default audio2 channel == 'alarm'");
var audio3 = document.getElementById("audio3");
ok(audio3, "Audio Element exists");
ok(audio3.mozAudioChannelType == "content", "Default audio3 channel == 'content'");
try {
audio3.mozAudioChannelType = "foo";
} catch(e) {}
ok(audio3.mozAudioChannelType == "normal", "audio3 channel == 'normal'");
audio3.mozAudioChannelType = "alarm";
ok(audio3.mozAudioChannelType == "alarm", "audio3 channel == 'alarm'");
</script>
</pre>
</body>
</html>