mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
292a5ce0ff
@ -32,7 +32,7 @@ nsTextEquivUtils::GetNameFromSubtree(Accessible* aAccessible,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
gInitiatorAcc = aAccessible;
|
gInitiatorAcc = aAccessible;
|
||||||
if (GetRoleRule(aAccessible->Role()) == eFromSubtree) {
|
if (IsNameFromSubtreeAllowed(aAccessible)) {
|
||||||
//XXX: is it necessary to care the accessible is not a document?
|
//XXX: is it necessary to care the accessible is not a document?
|
||||||
if (aAccessible->IsContent()) {
|
if (aAccessible->IsContent()) {
|
||||||
nsAutoString name;
|
nsAutoString name;
|
||||||
|
@ -89,6 +89,14 @@ public:
|
|||||||
static nsresult AppendTextEquivFromTextContent(nsIContent *aContent,
|
static nsresult AppendTextEquivFromTextContent(nsIContent *aContent,
|
||||||
nsAString *aString);
|
nsAString *aString);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the given accessible allows name from subtree.
|
||||||
|
*/
|
||||||
|
static bool IsNameFromSubtreeAllowed(Accessible* aAccessible)
|
||||||
|
{
|
||||||
|
return GetRoleRule(aAccessible->Role()) == eFromSubtree;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Iterates accessible children and calculates text equivalent from each
|
* Iterates accessible children and calculates text equivalent from each
|
||||||
|
@ -275,7 +275,7 @@ Accessible::Name(nsString& aName)
|
|||||||
|
|
||||||
ENameValueFlag nameFlag = NativeName(aName);
|
ENameValueFlag nameFlag = NativeName(aName);
|
||||||
if (!aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
return eNameOK;
|
return nameFlag;
|
||||||
|
|
||||||
// In the end get the name from tooltip.
|
// In the end get the name from tooltip.
|
||||||
if (mContent->IsHTML()) {
|
if (mContent->IsHTML()) {
|
||||||
@ -288,14 +288,12 @@ Accessible::Name(nsString& aName)
|
|||||||
aName.CompressWhitespace();
|
aName.CompressWhitespace();
|
||||||
return eNameFromTooltip;
|
return eNameFromTooltip;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return eNameOK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameFlag != eNoNameOnPurpose)
|
if (nameFlag != eNoNameOnPurpose)
|
||||||
aName.SetIsVoid(true);
|
aName.SetIsVoid(true);
|
||||||
|
|
||||||
return eNameOK;
|
return nameFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
@ -1055,7 +1053,7 @@ Accessible::TakeFocus()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
ENameValueFlag
|
||||||
Accessible::GetHTMLName(nsString& aLabel)
|
Accessible::GetHTMLName(nsString& aLabel)
|
||||||
{
|
{
|
||||||
Accessible* labelAcc = nullptr;
|
Accessible* labelAcc = nullptr;
|
||||||
@ -1066,8 +1064,11 @@ Accessible::GetHTMLName(nsString& aLabel)
|
|||||||
aLabel.CompressWhitespace();
|
aLabel.CompressWhitespace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aLabel.IsEmpty())
|
if (!aLabel.IsEmpty())
|
||||||
nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
|
return eNameOK;
|
||||||
|
|
||||||
|
nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
|
||||||
|
return aLabel.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1082,7 +1083,7 @@ Accessible::GetHTMLName(nsString& aLabel)
|
|||||||
* the control that uses the control="controlID" syntax will use
|
* the control that uses the control="controlID" syntax will use
|
||||||
* the child label for its Name.
|
* the child label for its Name.
|
||||||
*/
|
*/
|
||||||
void
|
ENameValueFlag
|
||||||
Accessible::GetXULName(nsString& aName)
|
Accessible::GetXULName(nsString& aName)
|
||||||
{
|
{
|
||||||
// CASE #1 (via label attribute) -- great majority of the cases
|
// CASE #1 (via label attribute) -- great majority of the cases
|
||||||
@ -1125,10 +1126,9 @@ Accessible::GetXULName(nsString& aName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX If CompressWhiteSpace worked on nsAString we could avoid a copy
|
|
||||||
aName.CompressWhitespace();
|
aName.CompressWhitespace();
|
||||||
if (!aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
return;
|
return eNameOK;
|
||||||
|
|
||||||
// Can get text from title of <toolbaritem> if we're a child of a <toolbaritem>
|
// Can get text from title of <toolbaritem> if we're a child of a <toolbaritem>
|
||||||
nsIContent *bindingParent = mContent->GetBindingParent();
|
nsIContent *bindingParent = mContent->GetBindingParent();
|
||||||
@ -1138,12 +1138,13 @@ Accessible::GetXULName(nsString& aName)
|
|||||||
if (parent->Tag() == nsGkAtoms::toolbaritem &&
|
if (parent->Tag() == nsGkAtoms::toolbaritem &&
|
||||||
parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
|
parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
|
||||||
aName.CompressWhitespace();
|
aName.CompressWhitespace();
|
||||||
return;
|
return eNameOK;
|
||||||
}
|
}
|
||||||
parent = parent->GetParent();
|
parent = parent->GetParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||||
|
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
@ -1229,6 +1230,13 @@ Accessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
|||||||
if (State() & states::CHECKABLE)
|
if (State() & states::CHECKABLE)
|
||||||
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::checkable, NS_LITERAL_STRING("true"));
|
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::checkable, NS_LITERAL_STRING("true"));
|
||||||
|
|
||||||
|
// Expose 'explicit-name' attribute.
|
||||||
|
if (!nsTextEquivUtils::IsNameFromSubtreeAllowed(this) ||
|
||||||
|
Name(oldValueUnused) != eNameFromSubtree) {
|
||||||
|
attributes->SetStringProperty(NS_LITERAL_CSTRING("explicit-name"),
|
||||||
|
NS_LITERAL_STRING("true"), oldValueUnused);
|
||||||
|
}
|
||||||
|
|
||||||
// Group attributes (level/setsize/posinset)
|
// Group attributes (level/setsize/posinset)
|
||||||
GroupPos groupPos = GroupPosition();
|
GroupPos groupPos = GroupPosition();
|
||||||
nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level,
|
nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level,
|
||||||
@ -2420,23 +2428,18 @@ Accessible::Shutdown()
|
|||||||
|
|
||||||
// Accessible protected
|
// Accessible protected
|
||||||
void
|
void
|
||||||
Accessible::ARIAName(nsAString& aName)
|
Accessible::ARIAName(nsString& aName)
|
||||||
{
|
{
|
||||||
nsAutoString label;
|
|
||||||
|
|
||||||
// aria-labelledby now takes precedence over aria-label
|
// aria-labelledby now takes precedence over aria-label
|
||||||
nsresult rv = nsTextEquivUtils::
|
nsresult rv = nsTextEquivUtils::
|
||||||
GetTextEquivFromIDRefs(this, nsGkAtoms::aria_labelledby, label);
|
GetTextEquivFromIDRefs(this, nsGkAtoms::aria_labelledby, aName);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
label.CompressWhitespace();
|
aName.CompressWhitespace();
|
||||||
aName = label;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label.IsEmpty() &&
|
if (aName.IsEmpty() &&
|
||||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label,
|
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label, aName)) {
|
||||||
label)) {
|
aName.CompressWhitespace();
|
||||||
label.CompressWhitespace();
|
|
||||||
aName = label;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2445,9 +2448,10 @@ ENameValueFlag
|
|||||||
Accessible::NativeName(nsString& aName)
|
Accessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
if (mContent->IsHTML())
|
if (mContent->IsHTML())
|
||||||
GetHTMLName(aName);
|
return GetHTMLName(aName);
|
||||||
else if (mContent->IsXUL())
|
|
||||||
GetXULName(aName);
|
if (mContent->IsXUL())
|
||||||
|
return GetXULName(aName);
|
||||||
|
|
||||||
return eNameOK;
|
return eNameOK;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,11 @@ enum ENameValueFlag {
|
|||||||
*/
|
*/
|
||||||
eNoNameOnPurpose,
|
eNoNameOnPurpose,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name was computed from the subtree.
|
||||||
|
*/
|
||||||
|
eNameFromSubtree,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tooltip was used as a name.
|
* Tooltip was used as a name.
|
||||||
*/
|
*/
|
||||||
@ -805,13 +810,13 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* Returns the accessible name specified by ARIA.
|
* Returns the accessible name specified by ARIA.
|
||||||
*/
|
*/
|
||||||
void ARIAName(nsAString& aName);
|
void ARIAName(nsString& aName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the name of HTML/XUL node.
|
* Compute the name of HTML/XUL node.
|
||||||
*/
|
*/
|
||||||
void GetHTMLName(nsString& aName);
|
mozilla::a11y::ENameValueFlag GetHTMLName(nsString& aName);
|
||||||
void GetXULName(nsString& aName);
|
mozilla::a11y::ENameValueFlag GetXULName(nsString& aName);
|
||||||
|
|
||||||
// helper method to verify frames
|
// helper method to verify frames
|
||||||
static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut);
|
static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut);
|
||||||
|
@ -1953,12 +1953,14 @@ HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartIndex,
|
|||||||
ENameValueFlag
|
ENameValueFlag
|
||||||
HyperTextAccessible::NativeName(nsString& aName)
|
HyperTextAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
AccessibleWrap::NativeName(aName);
|
ENameValueFlag nameFlag = AccessibleWrap::NativeName(aName);
|
||||||
|
if (!aName.IsEmpty())
|
||||||
|
return nameFlag;
|
||||||
|
|
||||||
// Get name from title attribute for HTML abbr and acronym elements making it
|
// Get name from title attribute for HTML abbr and acronym elements making it
|
||||||
// a valid name from markup. Otherwise their name isn't picked up by recursive
|
// a valid name from markup. Otherwise their name isn't picked up by recursive
|
||||||
// name computation algorithm. See NS_OK_NAME_FROM_TOOLTIP.
|
// name computation algorithm. See NS_OK_NAME_FROM_TOOLTIP.
|
||||||
if (aName.IsEmpty() && IsAbbreviation() &&
|
if (IsAbbreviation() &&
|
||||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName))
|
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName))
|
||||||
aName.CompressWhitespace();
|
aName.CompressWhitespace();
|
||||||
|
|
||||||
|
@ -77,16 +77,15 @@ ImageAccessible::NativeName(nsString& aName)
|
|||||||
if (!aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
return eNameOK;
|
return eNameOK;
|
||||||
|
|
||||||
Accessible::NativeName(aName);
|
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||||
if (aName.IsEmpty() && hasAltAttrib) {
|
if (!aName.IsEmpty())
|
||||||
// No accessible name but empty 'alt' attribute is present. If further name
|
return nameFlag;
|
||||||
// computation algorithm doesn't provide non empty name then it means
|
|
||||||
// an empty 'alt' attribute was used to indicate a decorative image (see
|
|
||||||
// nsIAccessible::name attribute for details).
|
|
||||||
return eNoNameOnPurpose;
|
|
||||||
}
|
|
||||||
|
|
||||||
return eNameOK;
|
// No accessible name but empty 'alt' attribute is present. If further name
|
||||||
|
// computation algorithm doesn't provide non empty name then it means
|
||||||
|
// an empty 'alt' attribute was used to indicate a decorative image (see
|
||||||
|
// Accessible::Name() method for details).
|
||||||
|
return hasAltAttrib ? eNoNameOnPurpose : eNameOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
role
|
role
|
||||||
|
@ -58,7 +58,7 @@ ENameValueFlag
|
|||||||
HTMLLabelAccessible::NativeName(nsString& aName)
|
HTMLLabelAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||||
return eNameOK;
|
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||||
}
|
}
|
||||||
|
|
||||||
role
|
role
|
||||||
|
@ -259,13 +259,13 @@ HTMLButtonAccessible::NativeRole()
|
|||||||
ENameValueFlag
|
ENameValueFlag
|
||||||
HTMLButtonAccessible::NativeName(nsString& aName)
|
HTMLButtonAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
Accessible::NativeName(aName);
|
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||||
if (!aName.IsEmpty() || mContent->Tag() != nsGkAtoms::input)
|
if (!aName.IsEmpty() || mContent->Tag() != nsGkAtoms::input)
|
||||||
return eNameOK;
|
return nameFlag;
|
||||||
|
|
||||||
// No name from HTML or ARIA
|
// Note: No need to check @value attribute since it results in anonymous text
|
||||||
if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName) &&
|
// node. The name is calculated from subtree in this case.
|
||||||
!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName)) {
|
if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName)) {
|
||||||
// Use the button's (default) label if nothing else works
|
// Use the button's (default) label if nothing else works
|
||||||
nsIFrame* frame = GetFrame();
|
nsIFrame* frame = GetFrame();
|
||||||
if (frame) {
|
if (frame) {
|
||||||
@ -323,9 +323,9 @@ HTMLTextFieldAccessible::NativeRole()
|
|||||||
ENameValueFlag
|
ENameValueFlag
|
||||||
HTMLTextFieldAccessible::NativeName(nsString& aName)
|
HTMLTextFieldAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
Accessible::NativeName(aName);
|
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||||
if (!aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
return eNameOK;
|
return nameFlag;
|
||||||
|
|
||||||
if (mContent->GetBindingParent()) {
|
if (mContent->GetBindingParent()) {
|
||||||
// XXX: bug 459640
|
// XXX: bug 459640
|
||||||
@ -613,9 +613,9 @@ HTMLGroupboxAccessible::GetLegend()
|
|||||||
ENameValueFlag
|
ENameValueFlag
|
||||||
HTMLGroupboxAccessible::NativeName(nsString& aName)
|
HTMLGroupboxAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
Accessible::NativeName(aName);
|
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||||
if (!aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
return eNameOK;
|
return nameFlag;
|
||||||
|
|
||||||
nsIContent* legendContent = GetLegend();
|
nsIContent* legendContent = GetLegend();
|
||||||
if (legendContent)
|
if (legendContent)
|
||||||
@ -696,9 +696,9 @@ HTMLFigureAccessible::NativeRole()
|
|||||||
ENameValueFlag
|
ENameValueFlag
|
||||||
HTMLFigureAccessible::NativeName(nsString& aName)
|
HTMLFigureAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
HyperTextAccessibleWrap::NativeName(aName);
|
ENameValueFlag nameFlag = HyperTextAccessibleWrap::NativeName(aName);
|
||||||
if (!aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
return eNameOK;
|
return nameFlag;
|
||||||
|
|
||||||
nsIContent* captionContent = Caption();
|
nsIContent* captionContent = Caption();
|
||||||
if (captionContent)
|
if (captionContent)
|
||||||
|
@ -163,9 +163,9 @@ HTMLAreaAccessible::
|
|||||||
ENameValueFlag
|
ENameValueFlag
|
||||||
HTMLAreaAccessible::NativeName(nsString& aName)
|
HTMLAreaAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
Accessible::NativeName(aName);
|
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||||
if (!aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
return eNameOK;
|
return nameFlag;
|
||||||
|
|
||||||
if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
|
if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
|
||||||
GetValue(aName);
|
GetValue(aName);
|
||||||
|
@ -200,6 +200,7 @@ HTMLSelectOptionAccessible::NativeName(nsString& aName)
|
|||||||
if (text && text->IsNodeOfType(nsINode::eTEXT)) {
|
if (text && text->IsNodeOfType(nsINode::eTEXT)) {
|
||||||
nsTextEquivUtils::AppendTextEquivFromTextContent(text, &aName);
|
nsTextEquivUtils::AppendTextEquivFromTextContent(text, &aName);
|
||||||
aName.CompressWhitespace();
|
aName.CompressWhitespace();
|
||||||
|
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||||
}
|
}
|
||||||
|
|
||||||
return eNameOK;
|
return eNameOK;
|
||||||
|
@ -388,9 +388,9 @@ HTMLTableAccessible::NativeState()
|
|||||||
ENameValueFlag
|
ENameValueFlag
|
||||||
HTMLTableAccessible::NativeName(nsString& aName)
|
HTMLTableAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
Accessible::NativeName(aName);
|
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||||
if (!aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
return eNameOK;
|
return nameFlag;
|
||||||
|
|
||||||
// Use table caption as a name.
|
// Use table caption as a name.
|
||||||
Accessible* caption = Caption();
|
Accessible* caption = Caption();
|
||||||
|
@ -125,10 +125,11 @@ ENameValueFlag
|
|||||||
XULLinkAccessible::NativeName(nsString& aName)
|
XULLinkAccessible::NativeName(nsString& aName)
|
||||||
{
|
{
|
||||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
|
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
|
||||||
if (aName.IsEmpty())
|
if (!aName.IsEmpty())
|
||||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
return eNameOK;
|
||||||
|
|
||||||
return eNameOK;
|
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||||
|
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||||
}
|
}
|
||||||
|
|
||||||
role
|
role
|
||||||
|
@ -634,8 +634,7 @@ XULListitemAccessible::NativeName(nsString& aName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetXULName(aName);
|
return GetXULName(aName);
|
||||||
return eNameOK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
role
|
role
|
||||||
|
@ -188,6 +188,11 @@ function testNameForAttrRule(aElm, aRule)
|
|||||||
|
|
||||||
var msg = "Attribute '" + attr + "' test. ";
|
var msg = "Attribute '" + attr + "' test. ";
|
||||||
testName(aElm, name, msg);
|
testName(aElm, name, msg);
|
||||||
|
if (aRule.getAttribute("explict-name") != "false")
|
||||||
|
testAttrs(aElm, {"explicit-name" : "true"}, true);
|
||||||
|
else
|
||||||
|
testAbsentAttrs(aElm, {"explicit-name" : "true"});
|
||||||
|
|
||||||
aElm.removeAttribute(attr);
|
aElm.removeAttribute(attr);
|
||||||
|
|
||||||
gTestIterator.iterateNext();
|
gTestIterator.iterateNext();
|
||||||
@ -235,6 +240,7 @@ function testNameForElmRule(aElm, aRule)
|
|||||||
|
|
||||||
var msg = "Element '" + tagname + "' test.";
|
var msg = "Element '" + tagname + "' test.";
|
||||||
testName(aElm, labelElm.getAttribute("a11yname"), msg);
|
testName(aElm, labelElm.getAttribute("a11yname"), msg);
|
||||||
|
testAttrs(aElm, {"explicit-name" : "true"}, true);
|
||||||
|
|
||||||
var parentNode = labelElm.parentNode;
|
var parentNode = labelElm.parentNode;
|
||||||
|
|
||||||
@ -252,6 +258,7 @@ function testNameForSubtreeRule(aElm, aRule)
|
|||||||
{
|
{
|
||||||
var msg = "From subtree test.";
|
var msg = "From subtree test.";
|
||||||
testName(aElm, aElm.getAttribute("a11yname"), msg);
|
testName(aElm, aElm.getAttribute("a11yname"), msg);
|
||||||
|
testAbsentAttrs(aElm, {"explicit-name" : "true"});
|
||||||
|
|
||||||
if (gDumpToConsole) {
|
if (gDumpToConsole) {
|
||||||
dump("\nProcessed from subtree rule. Wait for reorder event on " +
|
dump("\nProcessed from subtree rule. Wait for reorder event on " +
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
<!-- specific -->
|
<!-- specific -->
|
||||||
<ruleset id="htmlinputbutton">
|
<ruleset id="htmlinputbutton">
|
||||||
<ruleset ref="htmlelm_start"/>
|
<ruleset ref="htmlelm_start"/>
|
||||||
<rule attr="value" type="string"/>
|
<rule attr="value" type="string" explict-name="false"/>
|
||||||
<rule attr="alt" type="string"/>
|
<rule attr="alt" type="string"/>
|
||||||
<rule attr="src" type="string"/>
|
<rule attr="src" type="string"/>
|
||||||
<rule attr="data" type="string"/>
|
<rule attr="data" type="string"/>
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
src="../events.js"></script>
|
src="../events.js"></script>
|
||||||
<script type="application/javascript"
|
<script type="application/javascript"
|
||||||
src="../name.js"></script>
|
src="../name.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../attributes.js"></script>
|
||||||
|
|
||||||
<script type="application/javascript"
|
<script type="application/javascript"
|
||||||
src="markup.js"></script>
|
src="markup.js"></script>
|
||||||
|
@ -26,16 +26,24 @@ const SELF_DESTRUCT_TIMEOUT =
|
|||||||
Services.prefs.getIntPref("b2g.update.self-destruct-timeout");
|
Services.prefs.getIntPref("b2g.update.self-destruct-timeout");
|
||||||
|
|
||||||
const APPLY_IDLE_TIMEOUT_SECONDS = APPLY_IDLE_TIMEOUT / 1000;
|
const APPLY_IDLE_TIMEOUT_SECONDS = APPLY_IDLE_TIMEOUT / 1000;
|
||||||
|
const NETWORK_ERROR_OFFLINE = 111;
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(Services, "aus",
|
XPCOMUtils.defineLazyServiceGetter(Services, "aus",
|
||||||
"@mozilla.org/updates/update-service;1",
|
"@mozilla.org/updates/update-service;1",
|
||||||
"nsIApplicationUpdateService");
|
"nsIApplicationUpdateService");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(Services, "um",
|
||||||
|
"@mozilla.org/updates/update-manager;1",
|
||||||
|
"nsIUpdateManager");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(Services, "idle",
|
XPCOMUtils.defineLazyServiceGetter(Services, "idle",
|
||||||
"@mozilla.org/widget/idleservice;1",
|
"@mozilla.org/widget/idleservice;1",
|
||||||
"nsIIdleService");
|
"nsIIdleService");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(Services, "settings",
|
||||||
|
"@mozilla.org/settingsService;1",
|
||||||
|
"nsISettingsService");
|
||||||
|
|
||||||
function UpdatePrompt() {
|
function UpdatePrompt() {
|
||||||
this.wrappedJSObject = this;
|
this.wrappedJSObject = this;
|
||||||
}
|
}
|
||||||
@ -43,6 +51,7 @@ function UpdatePrompt() {
|
|||||||
UpdatePrompt.prototype = {
|
UpdatePrompt.prototype = {
|
||||||
classID: Components.ID("{88b3eb21-d072-4e3b-886d-f89d8c49fe59}"),
|
classID: Components.ID("{88b3eb21-d072-4e3b-886d-f89d8c49fe59}"),
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt,
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt,
|
||||||
|
Ci.nsIUpdateCheckListener,
|
||||||
Ci.nsIRequestObserver,
|
Ci.nsIRequestObserver,
|
||||||
Ci.nsIProgressEventSink,
|
Ci.nsIProgressEventSink,
|
||||||
Ci.nsIObserver]),
|
Ci.nsIObserver]),
|
||||||
@ -88,14 +97,52 @@ UpdatePrompt.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
showUpdateError: function UP_showUpdateError(aUpdate) {
|
showUpdateError: function UP_showUpdateError(aUpdate) {
|
||||||
if (aUpdate.state == "failed") {
|
log("Update error, state: " + aUpdate.state + ", errorCode: " +
|
||||||
log("Failed to download update, errorCode: " + aUpdate.errorCode);
|
aUpdate.errorCode);
|
||||||
}
|
|
||||||
|
this.sendUpdateEvent("update-error", aUpdate);
|
||||||
|
this.setUpdateStatus(aUpdate.statusText);
|
||||||
},
|
},
|
||||||
|
|
||||||
showUpdateHistory: function UP_showUpdateHistory(aParent) { },
|
showUpdateHistory: function UP_showUpdateHistory(aParent) { },
|
||||||
showUpdateInstalled: function UP_showUpdateInstalled() { },
|
showUpdateInstalled: function UP_showUpdateInstalled() { },
|
||||||
|
|
||||||
|
// nsIUpdateCheckListener
|
||||||
|
|
||||||
|
onCheckComplete: function UP_onCheckComplete(request, updates, updateCount) {
|
||||||
|
if (Services.um.activeUpdate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateCount == 0) {
|
||||||
|
this.setUpdateStatus("no-updates");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let update = Services.aus.selectUpdate(updates, updateCount);
|
||||||
|
if (!update) {
|
||||||
|
this.setUpdateStatus("already-latest-version");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setUpdateStatus("check-complete");
|
||||||
|
this.showUpdateAvailable(update);
|
||||||
|
},
|
||||||
|
|
||||||
|
onError: function UP_onError(request, update) {
|
||||||
|
if (update.errorCode == NETWORK_ERROR_OFFLINE) {
|
||||||
|
this.setUpdateStatus("retry-when-online");
|
||||||
|
}
|
||||||
|
|
||||||
|
Services.aus.QueryInterface(Ci.nsIUpdateCheckListener);
|
||||||
|
Services.aus.onError(request, update);
|
||||||
|
},
|
||||||
|
|
||||||
|
onProgress: function UP_onProgress(request, position, totalSize) {
|
||||||
|
Services.aus.QueryInterface(Ci.nsIUpdateCheckListener);
|
||||||
|
Services.aus.onProgress(request, position, totalSize);
|
||||||
|
},
|
||||||
|
|
||||||
// Custom functions
|
// Custom functions
|
||||||
|
|
||||||
waitForIdle: function UP_waitForIdle() {
|
waitForIdle: function UP_waitForIdle() {
|
||||||
@ -108,6 +155,13 @@ UpdatePrompt.prototype = {
|
|||||||
Services.obs.addObserver(this, "quit-application", false);
|
Services.obs.addObserver(this, "quit-application", false);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setUpdateStatus: function UP_setUpdateStatus(aStatus) {
|
||||||
|
log("Setting gecko.updateStatus: " + aStatus);
|
||||||
|
|
||||||
|
let lock = Services.settings.createLock();
|
||||||
|
lock.set("gecko.updateStatus", aStatus, null);
|
||||||
|
},
|
||||||
|
|
||||||
showApplyPrompt: function UP_showApplyPrompt(aUpdate) {
|
showApplyPrompt: function UP_showApplyPrompt(aUpdate) {
|
||||||
if (!this.sendUpdateEvent("update-prompt-apply", aUpdate)) {
|
if (!this.sendUpdateEvent("update-prompt-apply", aUpdate)) {
|
||||||
log("Unable to prompt, forcing restart");
|
log("Unable to prompt, forcing restart");
|
||||||
@ -123,22 +177,26 @@ UpdatePrompt.prototype = {
|
|||||||
sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
|
sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
|
||||||
let detail = {
|
let detail = {
|
||||||
displayVersion: aUpdate.displayVersion,
|
displayVersion: aUpdate.displayVersion,
|
||||||
detailsURL: aUpdate.detailsURL
|
detailsURL: aUpdate.detailsURL,
|
||||||
|
statusText: aUpdate.statusText,
|
||||||
|
state: aUpdate.state,
|
||||||
|
errorCode: aUpdate.errorCode,
|
||||||
|
isOSUpdate: aUpdate.isOSUpdate
|
||||||
};
|
};
|
||||||
|
|
||||||
let patch = aUpdate.selectedPatch;
|
let patch = aUpdate.selectedPatch;
|
||||||
if (!patch) {
|
if (!patch && aUpdate.patchCount > 0) {
|
||||||
// For now we just check the first patch to get size information if a
|
// For now we just check the first patch to get size information if a
|
||||||
// patch hasn't been selected yet.
|
// patch hasn't been selected yet.
|
||||||
if (aUpdate.patchCount == 0) {
|
|
||||||
log("Warning: no patches available in update");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
patch = aUpdate.getPatchAt(0);
|
patch = aUpdate.getPatchAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
detail.size = patch.size;
|
if (patch) {
|
||||||
detail.updateType = patch.type;
|
detail.size = patch.size;
|
||||||
|
detail.updateType = patch.type;
|
||||||
|
} else {
|
||||||
|
log("Warning: no patches available in update");
|
||||||
|
}
|
||||||
|
|
||||||
this._update = aUpdate;
|
this._update = aUpdate;
|
||||||
return this.sendChromeEvent(aType, detail);
|
return this.sendChromeEvent(aType, detail);
|
||||||
@ -252,11 +310,17 @@ UpdatePrompt.prototype = {
|
|||||||
forceUpdateCheck: function UP_forceUpdateCheck() {
|
forceUpdateCheck: function UP_forceUpdateCheck() {
|
||||||
log("Forcing update check");
|
log("Forcing update check");
|
||||||
|
|
||||||
|
// If we already have an active update available, don't try to
|
||||||
|
// download again, just prompt for install.
|
||||||
|
if (Services.um.activeUpdate) {
|
||||||
|
this.setUpdateStatus("check-complete");
|
||||||
|
this.showApplyPrompt(Services.um.activeUpdate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let checker = Cc["@mozilla.org/updates/update-checker;1"]
|
let checker = Cc["@mozilla.org/updates/update-checker;1"]
|
||||||
.createInstance(Ci.nsIUpdateChecker);
|
.createInstance(Ci.nsIUpdateChecker);
|
||||||
|
checker.checkForUpdates(this, true);
|
||||||
Services.aus.QueryInterface(Ci.nsIUpdateCheckListener);
|
|
||||||
checker.checkForUpdates(Services.aus, true);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleEvent: function UP_handleEvent(evt) {
|
handleEvent: function UP_handleEvent(evt) {
|
||||||
|
@ -178,6 +178,24 @@ let SocialUI = {
|
|||||||
|
|
||||||
haveLoggedInUser: function SocialUI_haveLoggedInUser() {
|
haveLoggedInUser: function SocialUI_haveLoggedInUser() {
|
||||||
return !!(Social.provider && Social.provider.profile && Social.provider.profile.userName);
|
return !!(Social.provider && Social.provider.profile && Social.provider.profile.userName);
|
||||||
|
},
|
||||||
|
|
||||||
|
closeSocialPanelForLinkTraversal: function (target, linkNode) {
|
||||||
|
// No need to close the panel if this traversal was not retargeted
|
||||||
|
if (target == "" || target == "_self")
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check to see whether this link traversal was in a social panel
|
||||||
|
let win = linkNode.ownerDocument.defaultView;
|
||||||
|
let container = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIWebNavigation)
|
||||||
|
.QueryInterface(Ci.nsIDocShell)
|
||||||
|
.chromeEventHandler;
|
||||||
|
let containerParent = container.parentNode;
|
||||||
|
if (containerParent.classList.contains("social-panel") &&
|
||||||
|
containerParent instanceof Ci.nsIDOMXULPopupElement) {
|
||||||
|
containerParent.hidePopup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,7 +645,7 @@ var SocialToolbar = {
|
|||||||
let tbi = document.getElementById("social-toolbar-item");
|
let tbi = document.getElementById("social-toolbar-item");
|
||||||
tbi.hidden = !Social.uiVisible;
|
tbi.hidden = !Social.uiVisible;
|
||||||
if (!SocialUI.haveLoggedInUser()) {
|
if (!SocialUI.haveLoggedInUser()) {
|
||||||
let parent = document.getElementById("social-notification-box");
|
let parent = document.getElementById("social-notification-panel");
|
||||||
while (parent.hasChildNodes())
|
while (parent.hasChildNodes())
|
||||||
parent.removeChild(parent.firstChild);
|
parent.removeChild(parent.firstChild);
|
||||||
|
|
||||||
@ -662,7 +680,6 @@ var SocialToolbar = {
|
|||||||
let icons = provider.ambientNotificationIcons;
|
let icons = provider.ambientNotificationIcons;
|
||||||
let iconNames = Object.keys(icons);
|
let iconNames = Object.keys(icons);
|
||||||
let iconBox = document.getElementById("social-toolbar-item");
|
let iconBox = document.getElementById("social-toolbar-item");
|
||||||
let notifBox = document.getElementById("social-notification-box");
|
|
||||||
let panel = document.getElementById("social-notification-panel");
|
let panel = document.getElementById("social-notification-panel");
|
||||||
panel.hidden = false;
|
panel.hidden = false;
|
||||||
|
|
||||||
@ -780,7 +797,7 @@ var SocialToolbar = {
|
|||||||
if (image.getAttribute("src") != icon.iconURL)
|
if (image.getAttribute("src") != icon.iconURL)
|
||||||
image.setAttribute("src", icon.iconURL);
|
image.setAttribute("src", icon.iconURL);
|
||||||
}
|
}
|
||||||
notifBox.appendChild(notificationFrames);
|
panel.appendChild(notificationFrames);
|
||||||
iconBox.appendChild(iconContainers);
|
iconBox.appendChild(iconContainers);
|
||||||
|
|
||||||
for (let frame of createdFrames) {
|
for (let frame of createdFrames) {
|
||||||
@ -797,13 +814,12 @@ var SocialToolbar = {
|
|||||||
|
|
||||||
showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButtonBox) {
|
showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButtonBox) {
|
||||||
let panel = document.getElementById("social-notification-panel");
|
let panel = document.getElementById("social-notification-panel");
|
||||||
let notifBox = document.getElementById("social-notification-box");
|
|
||||||
let notificationFrameId = aToolbarButtonBox.getAttribute("notificationFrameId");
|
let notificationFrameId = aToolbarButtonBox.getAttribute("notificationFrameId");
|
||||||
let notificationFrame = document.getElementById(notificationFrameId);
|
let notificationFrame = document.getElementById(notificationFrameId);
|
||||||
|
|
||||||
// Clear dimensions on all browsers so the panel size will
|
// Clear dimensions on all browsers so the panel size will
|
||||||
// only use the selected browser.
|
// only use the selected browser.
|
||||||
let frameIter = notifBox.firstElementChild;
|
let frameIter = panel.firstElementChild;
|
||||||
while (frameIter) {
|
while (frameIter) {
|
||||||
frameIter.collapsed = (frameIter != notificationFrame);
|
frameIter.collapsed = (frameIter != notificationFrame);
|
||||||
frameIter = frameIter.nextElementSibling;
|
frameIter = frameIter.nextElementSibling;
|
||||||
|
@ -378,7 +378,6 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
|||||||
}
|
}
|
||||||
|
|
||||||
#full-screen-warning-container {
|
#full-screen-warning-container {
|
||||||
pointer-events: none;
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -393,10 +392,9 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
|||||||
}
|
}
|
||||||
|
|
||||||
#full-screen-warning-message {
|
#full-screen-warning-message {
|
||||||
pointer-events: auto;
|
|
||||||
/* We must specify a max-width, otherwise word-wrap:break-word doesn't
|
/* We must specify a max-width, otherwise word-wrap:break-word doesn't
|
||||||
work in descendant <description> and <label> elements. Bug 630864. */
|
work in descendant <description> and <label> elements. Bug 630864. */
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#full-screen-domain-text,
|
#full-screen-domain-text,
|
||||||
|
@ -2549,7 +2549,7 @@ let BrowserOnClick = {
|
|||||||
switch (elmId) {
|
switch (elmId) {
|
||||||
case "exceptionDialogButton":
|
case "exceptionDialogButton":
|
||||||
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_CLICK_ADD_EXCEPTION);
|
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_CLICK_ADD_EXCEPTION);
|
||||||
let params = { exceptionAdded : false, handlePrivateBrowsing : true };
|
let params = { exceptionAdded : false };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch (Services.prefs.getIntPref("browser.ssl_override_behavior")) {
|
switch (Services.prefs.getIntPref("browser.ssl_override_behavior")) {
|
||||||
@ -3911,6 +3911,12 @@ var XULBrowserWindow = {
|
|||||||
|
|
||||||
// Called before links are navigated to to allow us to retarget them if needed.
|
// Called before links are navigated to to allow us to retarget them if needed.
|
||||||
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
|
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
|
||||||
|
let target = this._onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
|
||||||
|
SocialUI.closeSocialPanelForLinkTraversal(target, linkNode);
|
||||||
|
return target;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
|
||||||
// Don't modify non-default targets or targets that aren't in top-level app
|
// Don't modify non-default targets or targets that aren't in top-level app
|
||||||
// tab docshells (isAppTab will be false for app tab subframes).
|
// tab docshells (isAppTab will be false for app tab subframes).
|
||||||
if (originalTarget != "" || !isAppTab)
|
if (originalTarget != "" || !isAppTab)
|
||||||
|
@ -267,9 +267,7 @@
|
|||||||
type="arrow"
|
type="arrow"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
consumeoutsideclicks="true"
|
consumeoutsideclicks="true"
|
||||||
noautofocus="true">
|
noautofocus="true"/>
|
||||||
<box id="social-notification-box" flex="1"></box>
|
|
||||||
</panel>
|
|
||||||
<panel id="social-flyout-panel"
|
<panel id="social-flyout-panel"
|
||||||
class="social-panel"
|
class="social-panel"
|
||||||
onpopupshown="SocialFlyout.onShown()"
|
onpopupshown="SocialFlyout.onShown()"
|
||||||
|
@ -911,5 +911,66 @@ function test21e() {
|
|||||||
ok(objLoadingContent.activated, "Test 21e, Plugin with id=" + plugin.id + " should be activated");
|
ok(objLoadingContent.activated, "Test 21e, Plugin with id=" + plugin.id + " should be activated");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||||
|
prepareTest(test22, gTestRoot + "plugin_test.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that a click-to-play plugin retains its activated state upon reloading
|
||||||
|
function test22() {
|
||||||
|
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 22, Should have a click-to-play notification");
|
||||||
|
|
||||||
|
// Plugin should start as CTP
|
||||||
|
var pluginNode = gTestBrowser.contentDocument.getElementById("test");
|
||||||
|
ok(pluginNode, "Test 22, Found plugin in page");
|
||||||
|
var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||||
|
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 22, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
|
||||||
|
|
||||||
|
// Activate
|
||||||
|
objLoadingContent.playPlugin();
|
||||||
|
is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 22, plugin should have started");
|
||||||
|
ok(pluginNode.activated, "Test 22, plugin should be activated");
|
||||||
|
|
||||||
|
// Reload plugin
|
||||||
|
var oldVal = pluginNode.getObjectValue();
|
||||||
|
pluginNode.src = pluginNode.src;
|
||||||
|
is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 22, Plugin should have retained activated state");
|
||||||
|
ok(pluginNode.activated, "Test 22, plugin should have remained activated");
|
||||||
|
// Sanity, ensure that we actually reloaded the instance, since this behavior might change in the future.
|
||||||
|
var pluginsDiffer;
|
||||||
|
try {
|
||||||
|
pluginNode.checkObjectValue(oldVal);
|
||||||
|
} catch (e) {
|
||||||
|
pluginsDiffer = true;
|
||||||
|
}
|
||||||
|
ok(pluginsDiffer, "Test 22, plugin should have reloaded");
|
||||||
|
|
||||||
|
prepareTest(test23, gTestRoot + "plugin_test.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that a click-to-play plugin resets its activated state when changing types
|
||||||
|
function test23() {
|
||||||
|
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 23, Should have a click-to-play notification");
|
||||||
|
|
||||||
|
// Plugin should start as CTP
|
||||||
|
var pluginNode = gTestBrowser.contentDocument.getElementById("test");
|
||||||
|
ok(pluginNode, "Test 23, Found plugin in page");
|
||||||
|
var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||||
|
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 23, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
|
||||||
|
|
||||||
|
// Activate
|
||||||
|
objLoadingContent.playPlugin();
|
||||||
|
is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 23, plugin should have started");
|
||||||
|
ok(pluginNode.activated, "Test 23, plugin should be activated");
|
||||||
|
|
||||||
|
// Reload plugin (this may need RunSoon() in the future when plugins change state asynchronously)
|
||||||
|
pluginNode.type = null;
|
||||||
|
pluginNode.src = pluginNode.src; // We currently don't properly change state just on type change, bug 767631
|
||||||
|
is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_NULL, "Test 23, plugin should be unloaded");
|
||||||
|
pluginNode.type = "application/x-test";
|
||||||
|
pluginNode.src = pluginNode.src;
|
||||||
|
is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_NULL, "Test 23, Plugin should not have activated");
|
||||||
|
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 23, Plugin should be click-to-play");
|
||||||
|
ok(!pluginNode.activated, "Test 23, plugin node should not be activated");
|
||||||
|
|
||||||
finishTest();
|
finishTest();
|
||||||
}
|
}
|
||||||
|
@ -111,5 +111,40 @@ var tests = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
port.postMessage({topic: "test-init"});
|
port.postMessage({topic: "test-init"});
|
||||||
|
},
|
||||||
|
|
||||||
|
testCloseOnLinkTraversal: function(next) {
|
||||||
|
|
||||||
|
function onTabOpen(event) {
|
||||||
|
gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, true);
|
||||||
|
is(panel.state, "closed", "flyout should be closed");
|
||||||
|
ok(true, "Link should open a new tab");
|
||||||
|
executeSoon(function(){
|
||||||
|
gBrowser.removeTab(event.target);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let panel = document.getElementById("social-flyout-panel");
|
||||||
|
let port = Social.provider.getWorkerPort();
|
||||||
|
ok(port, "provider has a port");
|
||||||
|
port.onmessage = function (e) {
|
||||||
|
let topic = e.data.topic;
|
||||||
|
switch (topic) {
|
||||||
|
case "test-init-done":
|
||||||
|
port.postMessage({topic: "test-flyout-open"});
|
||||||
|
break;
|
||||||
|
case "got-flyout-visibility":
|
||||||
|
if (e.data.result == "shown") {
|
||||||
|
// click on our test link
|
||||||
|
is(panel.state, "open", "flyout should be open");
|
||||||
|
gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, true);
|
||||||
|
let iframe = panel.firstChild;
|
||||||
|
iframe.contentDocument.getElementById('traversal').click();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
port.postMessage({topic: "test-init"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,5 +31,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body style="max-width: 250px;" onload="pingWorker();">
|
<body style="max-width: 250px;" onload="pingWorker();">
|
||||||
<p>This is a test social flyout panel.</p>
|
<p>This is a test social flyout panel.</p>
|
||||||
|
<a id="traversal" href="http://mochi.test">test link</a>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -25,9 +25,12 @@ _BROWSER_FILES = \
|
|||||||
browser_privacypane_4.js \
|
browser_privacypane_4.js \
|
||||||
browser_privacypane_5.js \
|
browser_privacypane_5.js \
|
||||||
browser_privacypane_6.js \
|
browser_privacypane_6.js \
|
||||||
browser_privacypane_7.js \
|
|
||||||
browser_privacypane_8.js \
|
browser_privacypane_8.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
_BROWSER_FILES += browser_privacypane_7.js
|
||||||
|
endif
|
||||||
|
|
||||||
libs:: $(_BROWSER_FILES)
|
libs:: $(_BROWSER_FILES)
|
||||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
||||||
|
@ -33,7 +33,7 @@ browser.jar:
|
|||||||
content/browser/preferences/permissions.js
|
content/browser/preferences/permissions.js
|
||||||
* content/browser/preferences/preferences.xul
|
* content/browser/preferences/preferences.xul
|
||||||
content/browser/preferences/privacy.xul
|
content/browser/preferences/privacy.xul
|
||||||
content/browser/preferences/privacy.js
|
* content/browser/preferences/privacy.js
|
||||||
content/browser/preferences/sanitize.xul
|
content/browser/preferences/sanitize.xul
|
||||||
content/browser/preferences/security.xul
|
content/browser/preferences/security.xul
|
||||||
content/browser/preferences/security.js
|
content/browser/preferences/security.js
|
||||||
|
@ -222,18 +222,22 @@ var gPrivacyPane = {
|
|||||||
|
|
||||||
observe: function PPP_observe(aSubject, aTopic, aData)
|
observe: function PPP_observe(aSubject, aTopic, aData)
|
||||||
{
|
{
|
||||||
let privateBrowsingService = Components.classes["@mozilla.org/privatebrowsing;1"].
|
|
||||||
getService(Components.interfaces.nsIPrivateBrowsingService);
|
|
||||||
|
|
||||||
// Toggle the private browsing mode without switching the session
|
// Toggle the private browsing mode without switching the session
|
||||||
let prefValue = document.getElementById("browser.privatebrowsing.autostart").value;
|
let prefValue = document.getElementById("browser.privatebrowsing.autostart").value;
|
||||||
let keepCurrentSession = document.getElementById("browser.privatebrowsing.keep_current_session");
|
let keepCurrentSession = document.getElementById("browser.privatebrowsing.keep_current_session");
|
||||||
keepCurrentSession.value = true;
|
keepCurrentSession.value = true;
|
||||||
|
|
||||||
|
#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
let privateBrowsingService = Components.classes["@mozilla.org/privatebrowsing;1"].
|
||||||
|
getService(Components.interfaces.nsIPrivateBrowsingService);
|
||||||
|
|
||||||
// If activating from within the private browsing mode, reset the
|
// If activating from within the private browsing mode, reset the
|
||||||
// private session
|
// private session
|
||||||
if (prefValue && privateBrowsingService.privateBrowsingEnabled)
|
if (prefValue && privateBrowsingService.privateBrowsingEnabled)
|
||||||
privateBrowsingService.privateBrowsingEnabled = false;
|
privateBrowsingService.privateBrowsingEnabled = false;
|
||||||
privateBrowsingService.privateBrowsingEnabled = prefValue;
|
privateBrowsingService.privateBrowsingEnabled = prefValue;
|
||||||
|
#endif
|
||||||
|
|
||||||
keepCurrentSession.reset();
|
keepCurrentSession.reset();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -23,11 +23,14 @@ _BROWSER_FILES = \
|
|||||||
browser_privacypane_4.js \
|
browser_privacypane_4.js \
|
||||||
browser_privacypane_5.js \
|
browser_privacypane_5.js \
|
||||||
browser_privacypane_6.js \
|
browser_privacypane_6.js \
|
||||||
browser_privacypane_7.js \
|
|
||||||
browser_privacypane_8.js \
|
browser_privacypane_8.js \
|
||||||
browser_permissions.js \
|
browser_permissions.js \
|
||||||
browser_chunk_permissions.js \
|
browser_chunk_permissions.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
_BROWSER_FILES += browser_privacypane_7.js
|
||||||
|
endif
|
||||||
|
|
||||||
libs:: $(_BROWSER_FILES)
|
libs:: $(_BROWSER_FILES)
|
||||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
||||||
|
@ -466,6 +466,7 @@ PrivateBrowsingService.prototype = {
|
|||||||
if (this._autoStarted)
|
if (this._autoStarted)
|
||||||
aSubject.handleFlag("private", false);
|
aSubject.handleFlag("private", false);
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref("browser.privatebrowsing.autostart", true);
|
||||||
this.privateBrowsingEnabled = true;
|
this.privateBrowsingEnabled = true;
|
||||||
this._autoStarted = true;
|
this._autoStarted = true;
|
||||||
this._lastChangedByCommandLine = true;
|
this._lastChangedByCommandLine = true;
|
||||||
|
@ -19,14 +19,13 @@ function test() {
|
|||||||
// enter private browsing mode
|
// enter private browsing mode
|
||||||
pb.privateBrowsingEnabled = true;
|
pb.privateBrowsingEnabled = true;
|
||||||
|
|
||||||
step1();
|
doTest();
|
||||||
|
|
||||||
// Test the certificate exceptions dialog as it is invoked from about:certerror
|
// Test the certificate exceptions dialog
|
||||||
function step1() {
|
function doTest() {
|
||||||
let params = {
|
let params = {
|
||||||
exceptionAdded : false,
|
exceptionAdded : false,
|
||||||
location: INVALID_CERT_LOCATION,
|
location: INVALID_CERT_LOCATION,
|
||||||
handlePrivateBrowsing : true,
|
|
||||||
prefetchCert: true,
|
prefetchCert: true,
|
||||||
};
|
};
|
||||||
function testCheckbox() {
|
function testCheckbox() {
|
||||||
@ -41,32 +40,6 @@ function test() {
|
|||||||
ok(!checkbox.hasAttribute("checked"),
|
ok(!checkbox.hasAttribute("checked"),
|
||||||
"the permanent checkbox should not be checked when handling the private browsing mode");
|
"the permanent checkbox should not be checked when handling the private browsing mode");
|
||||||
win.close();
|
win.close();
|
||||||
step2();
|
|
||||||
}, "cert-exception-ui-ready", false);
|
|
||||||
}
|
|
||||||
var win = openDialog(EXCEPTIONS_DLG_URL, "", EXCEPTIONS_DLG_FEATURES, params);
|
|
||||||
win.addEventListener("load", testCheckbox, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test the certificate excetions dialog as it is invoked from the Preferences dialog
|
|
||||||
function step2() {
|
|
||||||
let params = {
|
|
||||||
exceptionAdded : false,
|
|
||||||
location: INVALID_CERT_LOCATION,
|
|
||||||
prefetchCert: true,
|
|
||||||
};
|
|
||||||
function testCheckbox() {
|
|
||||||
win.removeEventListener("load", testCheckbox, false);
|
|
||||||
Services.obs.addObserver(function (aSubject, aTopic, aData) {
|
|
||||||
Services.obs.removeObserver(arguments.callee, "cert-exception-ui-ready", false);
|
|
||||||
ok(win.gCert, "The certificate information should be available now");
|
|
||||||
|
|
||||||
let checkbox = win.document.getElementById("permanent");
|
|
||||||
ok(!checkbox.hasAttribute("disabled"),
|
|
||||||
"the permanent checkbox should not be disabled when not handling the private browsing mode");
|
|
||||||
ok(checkbox.hasAttribute("checked"),
|
|
||||||
"the permanent checkbox should be checked when not handling the private browsing mode");
|
|
||||||
win.close();
|
|
||||||
cleanup();
|
cleanup();
|
||||||
}, "cert-exception-ui-ready", false);
|
}, "cert-exception-ui-ready", false);
|
||||||
}
|
}
|
||||||
|
@ -4111,7 +4111,6 @@ html|*#gcli-output-frame {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-notification-box,
|
|
||||||
.social-panel-frame {
|
.social-panel-frame {
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,6 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
|
|||||||
|
|
||||||
/*** Status and progress indicator ***/
|
/*** Status and progress indicator ***/
|
||||||
|
|
||||||
#downloads-button,
|
|
||||||
#downloads-indicator {
|
#downloads-indicator {
|
||||||
width: 35px;
|
width: 35px;
|
||||||
}
|
}
|
||||||
|
@ -3395,7 +3395,6 @@ html|*#gcli-output-frame {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-notification-box,
|
|
||||||
.social-panel-frame {
|
.social-panel-frame {
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ GCONF_VERSION=1.2.1
|
|||||||
GIO_VERSION=2.18
|
GIO_VERSION=2.18
|
||||||
STARTUP_NOTIFICATION_VERSION=0.8
|
STARTUP_NOTIFICATION_VERSION=0.8
|
||||||
DBUS_VERSION=0.60
|
DBUS_VERSION=0.60
|
||||||
SQLITE_VERSION=3.7.14
|
SQLITE_VERSION=3.7.14.1
|
||||||
|
|
||||||
MSMANIFEST_TOOL=
|
MSMANIFEST_TOOL=
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ interface nsIObjectLoadingContent : nsISupports
|
|||||||
const unsigned long PLUGIN_SUPPRESSED = 6;
|
const unsigned long PLUGIN_SUPPRESSED = 6;
|
||||||
// Blocked by content policy
|
// Blocked by content policy
|
||||||
const unsigned long PLUGIN_USER_DISABLED = 7;
|
const unsigned long PLUGIN_USER_DISABLED = 7;
|
||||||
|
/// ** All values >= PLUGIN_CLICK_TO_PLAY are plugin placeholder types that
|
||||||
|
/// would be replaced by a real plugin if activated (playPlugin())
|
||||||
// The plugin is disabled until the user clicks on it
|
// The plugin is disabled until the user clicks on it
|
||||||
const unsigned long PLUGIN_CLICK_TO_PLAY = 8;
|
const unsigned long PLUGIN_CLICK_TO_PLAY = 8;
|
||||||
// The plugin is vulnerable (update available)
|
// The plugin is vulnerable (update available)
|
||||||
@ -110,13 +112,14 @@ interface nsIObjectLoadingContent : nsISupports
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will play a plugin that has been stopped by the
|
* This method will play a plugin that has been stopped by the
|
||||||
* click-to-play plugins feature.
|
* click-to-play plugins or play-preview features.
|
||||||
*/
|
*/
|
||||||
void playPlugin();
|
void playPlugin();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This attribute will return true if the plugin has been activated and
|
* This attribute will return true if the current content type has been
|
||||||
* false if the plugin is still in the click-to-play or play preview state.
|
* activated, either explicitly or by passing checks that would have it be
|
||||||
|
* click-to-play or play-preview.
|
||||||
*/
|
*/
|
||||||
readonly attribute boolean activated;
|
readonly attribute boolean activated;
|
||||||
|
|
||||||
|
@ -187,6 +187,7 @@ LOCAL_INCLUDES += \
|
|||||||
-I$(topsrcdir)/dom/ipc \
|
-I$(topsrcdir)/dom/ipc \
|
||||||
-I$(topsrcdir)/image/src \
|
-I$(topsrcdir)/image/src \
|
||||||
-I$(topsrcdir)/js/xpconnect/src \
|
-I$(topsrcdir)/js/xpconnect/src \
|
||||||
|
-I$(topsrcdir)/layout/base \
|
||||||
-I$(topsrcdir)/layout/generic \
|
-I$(topsrcdir)/layout/generic \
|
||||||
-I$(topsrcdir)/layout/style \
|
-I$(topsrcdir)/layout/style \
|
||||||
-I$(topsrcdir)/layout/svg \
|
-I$(topsrcdir)/layout/svg \
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
#include "nsIRefreshURI.h"
|
#include "nsIRefreshURI.h"
|
||||||
#include "nsIWebNavigation.h"
|
#include "nsIWebNavigation.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
|
#include "nsStyleSheetService.h"
|
||||||
|
|
||||||
#include "nsNetUtil.h" // for NS_MakeAbsoluteURI
|
#include "nsNetUtil.h" // for NS_MakeAbsoluteURI
|
||||||
|
|
||||||
@ -2318,6 +2319,14 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AppendAuthorSheet(nsIStyleSheet *aSheet, void *aData)
|
||||||
|
{
|
||||||
|
nsStyleSet *styleSet = static_cast<nsStyleSet*>(aData);
|
||||||
|
styleSet->AppendStyleSheet(nsStyleSet::eDocSheet, aSheet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
|
nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
|
||||||
{
|
{
|
||||||
@ -2344,6 +2353,12 @@ nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
|
||||||
|
if (sheetService) {
|
||||||
|
sheetService->AuthorStyleSheets()->EnumerateForwards(AppendAuthorSheet,
|
||||||
|
aStyleSet);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = mCatalogSheets.Count() - 1; i >= 0; --i) {
|
for (i = mCatalogSheets.Count() - 1; i >= 0; --i) {
|
||||||
nsIStyleSheet* sheet = mCatalogSheets[i];
|
nsIStyleSheet* sheet = mCatalogSheets[i];
|
||||||
if (sheet->IsApplicable()) {
|
if (sheet->IsApplicable()) {
|
||||||
@ -3583,14 +3598,6 @@ nsDocument::GetStyleSheetAt(int32_t aIndex) const
|
|||||||
int32_t
|
int32_t
|
||||||
nsDocument::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const
|
nsDocument::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const
|
||||||
{
|
{
|
||||||
if (mAdditionalSheets[eUserSheet].IndexOf(aSheet) >= 0 ||
|
|
||||||
mAdditionalSheets[eAgentSheet].IndexOf(aSheet) >= 0 ) {
|
|
||||||
// Returning INT32_MAX to make sure that additional sheets are
|
|
||||||
// in the style set of the PresShell will be always after the
|
|
||||||
// document sheets (even if document sheets are added dynamically).
|
|
||||||
return INT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mStyleSheets.IndexOf(aSheet);
|
return mStyleSheets.IndexOf(aSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,9 +1470,15 @@ nsObjectLoadingContent::UpdateObjectParameters()
|
|||||||
mURI = newURI;
|
mURI = newURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mContentType != newMime) {
|
// We don't update content type when loading, as the type is not final and we
|
||||||
|
// don't want to superfluously change between mOriginalContentType ->
|
||||||
|
// mContentType when doing |obj.data = obj.data| with a channel and differing
|
||||||
|
// type.
|
||||||
|
if (mType != eType_Loading && mContentType != newMime) {
|
||||||
retval = (ParameterUpdateFlags)(retval | eParamStateChanged);
|
retval = (ParameterUpdateFlags)(retval | eParamStateChanged);
|
||||||
LOG(("OBJLC [%p]: Object effective mime type changed (%s -> %s)", this, mContentType.get(), newMime.get()));
|
retval = (ParameterUpdateFlags)(retval | eParamContentTypeChanged);
|
||||||
|
LOG(("OBJLC [%p]: Object effective mime type changed (%s -> %s)",
|
||||||
|
this, mContentType.get(), newMime.get()));
|
||||||
mContentType = newMime;
|
mContentType = newMime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1553,6 +1559,12 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Explicit user activation should reset if the object changes content types
|
||||||
|
if (mActivated && (stateChange & eParamContentTypeChanged)) {
|
||||||
|
LOG(("OBJLC [%p]: Content type changed, clearing activation state", this));
|
||||||
|
mActivated = false;
|
||||||
|
}
|
||||||
|
|
||||||
// We synchronously start/stop plugin instances below, which may spin the
|
// We synchronously start/stop plugin instances below, which may spin the
|
||||||
// event loop. Re-entering into the load is fine, but at that point the
|
// event loop. Re-entering into the load is fine, but at that point the
|
||||||
// original load call needs to abort when unwinding
|
// original load call needs to abort when unwinding
|
||||||
@ -1661,6 +1673,13 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||||||
fallbackType = clickToPlayReason;
|
fallbackType = clickToPlayReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mActivated && mType != eType_Null) {
|
||||||
|
// Object passed ShouldPlay and !ShouldPreview, so it should be considered
|
||||||
|
// activated until it changes content type
|
||||||
|
LOG(("OBJLC [%p]: Object implicitly activated", this));
|
||||||
|
mActivated = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Sanity check: We shouldn't have any loaded resources, pending events, or
|
// Sanity check: We shouldn't have any loaded resources, pending events, or
|
||||||
// a final listener at this point
|
// a final listener at this point
|
||||||
if (mFrameLoader || mPendingInstantiateEvent || mInstanceOwner ||
|
if (mFrameLoader || mPendingInstantiateEvent || mInstanceOwner ||
|
||||||
@ -2464,15 +2483,25 @@ nsObjectLoadingContent::PlayPlugin()
|
|||||||
if (!nsContentUtils::IsCallerChrome())
|
if (!nsContentUtils::IsCallerChrome())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
mActivated = true;
|
if (!mActivated) {
|
||||||
return LoadObject(true, true);
|
mActivated = true;
|
||||||
|
LOG(("OBJLC [%p]: Activated by user", this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're in a click-to-play or play preview state, we need to reload
|
||||||
|
// Fallback types >= eFallbackClickToPlay are plugin-replacement types, see
|
||||||
|
// header
|
||||||
|
if (mType == eType_Null && mFallbackType >= eFallbackClickToPlay) {
|
||||||
|
return LoadObject(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsObjectLoadingContent::GetActivated(bool *aActivated)
|
nsObjectLoadingContent::GetActivated(bool *aActivated)
|
||||||
{
|
{
|
||||||
FallbackType reason;
|
*aActivated = mActivated;
|
||||||
*aActivated = ShouldPlay(reason) && !ShouldPreview();
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2490,11 +2519,14 @@ nsObjectLoadingContent::CancelPlayPreview()
|
|||||||
if (!nsContentUtils::IsCallerChrome())
|
if (!nsContentUtils::IsCallerChrome())
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
if (mPlayPreviewCanceled || mActivated)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
mPlayPreviewCanceled = true;
|
mPlayPreviewCanceled = true;
|
||||||
return LoadObject(true, true);
|
|
||||||
|
// If we're in play preview state already, reload
|
||||||
|
if (mType == eType_Null && mFallbackType == eFallbackPlayPreview) {
|
||||||
|
return LoadObject(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -77,6 +77,8 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||||||
eFallbackSuppressed = nsIObjectLoadingContent::PLUGIN_SUPPRESSED,
|
eFallbackSuppressed = nsIObjectLoadingContent::PLUGIN_SUPPRESSED,
|
||||||
// Blocked by content policy
|
// Blocked by content policy
|
||||||
eFallbackUserDisabled = nsIObjectLoadingContent::PLUGIN_USER_DISABLED,
|
eFallbackUserDisabled = nsIObjectLoadingContent::PLUGIN_USER_DISABLED,
|
||||||
|
/// ** All values >= eFallbackClickToPlay are plugin placeholder types
|
||||||
|
/// that would be replaced by a real plugin if activated (PlayPlugin())
|
||||||
// The plugin is disabled until the user clicks on it
|
// The plugin is disabled until the user clicks on it
|
||||||
eFallbackClickToPlay = nsIObjectLoadingContent::PLUGIN_CLICK_TO_PLAY,
|
eFallbackClickToPlay = nsIObjectLoadingContent::PLUGIN_CLICK_TO_PLAY,
|
||||||
// The plugin is vulnerable (update available)
|
// The plugin is vulnerable (update available)
|
||||||
@ -222,7 +224,14 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||||||
eParamChannelChanged = PR_BIT(0),
|
eParamChannelChanged = PR_BIT(0),
|
||||||
// Parameters that affect displayed content changed
|
// Parameters that affect displayed content changed
|
||||||
// - mURI, mContentType, mType, mBaseURI
|
// - mURI, mContentType, mType, mBaseURI
|
||||||
eParamStateChanged = PR_BIT(1)
|
eParamStateChanged = PR_BIT(1),
|
||||||
|
// The effective content type changed, independant of object type. This
|
||||||
|
// can happen when changing from Loading -> Final type, but doesn't
|
||||||
|
// necessarily happen when changing between object types. E.g., if a PDF
|
||||||
|
// handler was installed between the last load of this object and now, we
|
||||||
|
// might change from eType_Document -> eType_Plugin without changing
|
||||||
|
// ContentType
|
||||||
|
eParamContentTypeChanged = PR_BIT(2)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,8 +81,7 @@ public:
|
|||||||
NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0;
|
NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0;
|
||||||
|
|
||||||
// This gets an Azure SourceSurface for the canvas, this will be a snapshot
|
// This gets an Azure SourceSurface for the canvas, this will be a snapshot
|
||||||
// of the canvas at the time it was called. This will return null for a
|
// of the canvas at the time it was called.
|
||||||
// non-azure canvas.
|
|
||||||
virtual mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() = 0;
|
virtual mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() = 0;
|
||||||
|
|
||||||
// If this context is opaque, the backing store of the canvas should
|
// If this context is opaque, the backing store of the canvas should
|
||||||
|
@ -40,17 +40,6 @@ function IsMacOSX10_5orOlder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function IsAzureEnabled() {
|
|
||||||
var enabled = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var backend = Cc["@mozilla.org/gfx/info;1"].getService(SpecialPowers.Ci.nsIGfxInfo).getInfo().AzureCanvasBackend;
|
|
||||||
enabled = (backend != "none");
|
|
||||||
} catch (e) { }
|
|
||||||
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
function IsAzureSkia() {
|
function IsAzureSkia() {
|
||||||
var enabled = false;
|
var enabled = false;
|
||||||
|
|
||||||
@ -3538,11 +3527,7 @@ var _thrown = undefined; try {
|
|||||||
ctx.drawImage(null, 0, 0);
|
ctx.drawImage(null, 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
|
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -3719,38 +3704,22 @@ var ctx = canvas.getContext('2d');
|
|||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.drawImage(undefined, 0, 0);
|
ctx.drawImage(undefined, 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.drawImage(0, 0, 0);
|
ctx.drawImage(0, 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.drawImage("", 0, 0);
|
ctx.drawImage("", 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.drawImage(document.createElement('p'), 0, 0);
|
ctx.drawImage(document.createElement('p'), 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -6151,16 +6120,9 @@ ctx.fillRect(0, 0, 100, 50);
|
|||||||
ctx.translate(-50, 0);
|
ctx.translate(-50, 0);
|
||||||
ctx.fillRect(50, 0, 100, 50);
|
ctx.fillRect(50, 0, 100, 50);
|
||||||
|
|
||||||
if (IsAzureEnabled()) {
|
isPixel(ctx, 25,25, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 25,25, 0,255,0,255, 0);
|
|
||||||
} else {
|
|
||||||
todo_isPixel(ctx, 25,25, 0,255,0,255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 75,25, 0,255,0,255, 0);
|
isPixel(ctx, 75,25, 0,255,0,255, 0);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -7348,15 +7310,9 @@ ctx.translate(50, 25);
|
|||||||
ctx.scale(10, 10);
|
ctx.scale(10, 10);
|
||||||
ctx.fillRect(-5, -2.5, 10, 5);
|
ctx.fillRect(-5, -2.5, 10, 5);
|
||||||
|
|
||||||
if (IsAzureEnabled()) {
|
isPixel(ctx, 25,25, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 25,25, 0,255,0,255, 0);
|
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
isPixel(ctx, 75,25, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 75,25, 0,255,0,255, 0);
|
|
||||||
} else {
|
|
||||||
todo_isPixel(ctx, 25,25, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 75,25, 0,255,0,255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -7717,11 +7673,7 @@ var ctx = canvas.getContext('2d');
|
|||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.createImageData(null);
|
ctx.createImageData(null);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -9233,11 +9185,7 @@ var ctx = canvas.getContext('2d');
|
|||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.putImageData(null, 0, 0);
|
ctx.putImageData(null, 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -9349,32 +9297,17 @@ var imgdata = { width: 1, height: 1, data: [255, 0, 0, 255] };
|
|||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.putImageData(imgdata, 0, 0);
|
ctx.putImageData(imgdata, 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.putImageData("cheese", 0, 0);
|
ctx.putImageData("cheese", 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.putImageData(42, 0, 0);
|
ctx.putImageData(42, 0, 0);
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -11681,13 +11614,7 @@ ctx.moveTo(0, 25);
|
|||||||
ctx.arc(200, 25, 0, 0, Math.PI, true);
|
ctx.arc(200, 25, 0, 0, Math.PI, true);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
if (IsAzureEnabled()) {
|
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
|
||||||
} else {
|
|
||||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -14425,7 +14352,7 @@ ctx.lineTo(50, 25);
|
|||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
if (IsAzureEnabled() && IsAzureSkia()) {
|
if (IsAzureSkia()) {
|
||||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
} else {
|
} else {
|
||||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
@ -14501,7 +14428,7 @@ ctx.moveTo(50, 25);
|
|||||||
ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
|
ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
if (IsAzureEnabled() && IsAzureSkia()) {
|
if (IsAzureSkia()) {
|
||||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
} else {
|
} else {
|
||||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
@ -14538,7 +14465,7 @@ ctx.moveTo(50, 25);
|
|||||||
ctx.lineTo(50, 25);
|
ctx.lineTo(50, 25);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
if (IsAzureEnabled() && IsAzureSkia()) {
|
if (IsAzureSkia()) {
|
||||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
} else {
|
} else {
|
||||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
@ -14575,7 +14502,7 @@ ctx.stroke();
|
|||||||
|
|
||||||
ctx.strokeRect(50, 25, 0, 0);
|
ctx.strokeRect(50, 25, 0, 0);
|
||||||
|
|
||||||
if (IsAzureEnabled() && IsAzureSkia()) {
|
if (IsAzureSkia()) {
|
||||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
} else {
|
} else {
|
||||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||||
@ -15173,13 +15100,7 @@ var ctx = canvas.getContext('2d');
|
|||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.createPattern(null, 'repeat');
|
ctx.createPattern(null, 'repeat');
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -15197,13 +15118,7 @@ var ctx = canvas.getContext('2d');
|
|||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.createPattern('image_red.png', 'repeat');
|
ctx.createPattern('image_red.png', 'repeat');
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -15221,13 +15136,7 @@ var ctx = canvas.getContext('2d');
|
|||||||
var _thrown = undefined; try {
|
var _thrown = undefined; try {
|
||||||
ctx.createPattern(undefined, 'repeat');
|
ctx.createPattern(undefined, 'repeat');
|
||||||
} catch (e) { _thrown = e };
|
} catch (e) { _thrown = e };
|
||||||
if (IsAzureEnabled()) {
|
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
||||||
ok(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
} else {
|
|
||||||
todo(_thrown && _thrown.name == "TypeError", "should throw TypeError");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -15727,18 +15636,10 @@ ctx.fillRect(0, 0, 100, 50);
|
|||||||
ctx.translate(-128, -78);
|
ctx.translate(-128, -78);
|
||||||
ctx.fillRect(128, 78, 100, 50);
|
ctx.fillRect(128, 78, 100, 50);
|
||||||
|
|
||||||
if (IsAzureEnabled()) {
|
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
} else {
|
|
||||||
todo_isPixel(ctx, 1,1, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<img src="image_rgrg-256x256.png" id="rgrg-256x256_4.png" class="resource">
|
<img src="image_rgrg-256x256.png" id="rgrg-256x256_4.png" class="resource">
|
||||||
@ -15831,22 +15732,12 @@ ctx.fillRect(0, -16, 100, 50);
|
|||||||
ctx.fillStyle = '#0f0';
|
ctx.fillStyle = '#0f0';
|
||||||
ctx.fillRect(0, 0, 100, 16);
|
ctx.fillRect(0, 0, 100, 16);
|
||||||
|
|
||||||
if (IsAzureEnabled()) {
|
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
} else {
|
|
||||||
todo_isPixel(ctx, 1,1, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
isPixel(ctx, 1,25, 0,255,0,255, 0);
|
isPixel(ctx, 1,25, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,25, 0,255,0,255, 0);
|
isPixel(ctx, 98,25, 0,255,0,255, 0);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<img src="image_red-16x16.png" id="red-16x16_1.png" class="resource">
|
<img src="image_red-16x16.png" id="red-16x16_1.png" class="resource">
|
||||||
@ -15877,16 +15768,8 @@ ctx.fillRect(0, 0, 100, 16);
|
|||||||
|
|
||||||
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
||||||
|
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
||||||
if (IsAzureEnabled()) {
|
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
|
||||||
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
} else {
|
|
||||||
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<img src="image_red-16x16.png" id="red-16x16_2.png" class="resource">
|
<img src="image_red-16x16.png" id="red-16x16_2.png" class="resource">
|
||||||
@ -15951,19 +15834,10 @@ ctx.fillRect(0, 0, 16, 50);
|
|||||||
isPixel(ctx, 50,1, 0,255,0,255, 0);
|
isPixel(ctx, 50,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 50,48, 0,255,0,255, 0);
|
isPixel(ctx, 50,48, 0,255,0,255, 0);
|
||||||
|
|
||||||
if (IsAzureEnabled()) {
|
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
} else {
|
|
||||||
todo_isPixel(ctx, 1,1, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<img src="image_red-16x16.png" id="red-16x16_3.png" class="resource">
|
<img src="image_red-16x16.png" id="red-16x16_3.png" class="resource">
|
||||||
@ -15994,15 +15868,8 @@ ctx.fillRect(0, 0, 16, 50);
|
|||||||
|
|
||||||
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
isPixel(ctx, 1,1, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
isPixel(ctx, 1,48, 0,255,0,255, 0);
|
||||||
|
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
||||||
if (IsAzureEnabled()) {
|
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
||||||
isPixel(ctx, 98,1, 0,255,0,255, 0);
|
|
||||||
isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
} else {
|
|
||||||
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
|
|
||||||
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<img src="image_red-16x16.png" id="red-16x16_4.png" class="resource">
|
<img src="image_red-16x16.png" id="red-16x16_4.png" class="resource">
|
||||||
@ -19648,11 +19515,7 @@ ok(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.p
|
|||||||
window.CanvasRenderingContext2D.prototype.fill = 1;
|
window.CanvasRenderingContext2D.prototype.fill = 1;
|
||||||
ok(window.CanvasRenderingContext2D.prototype.fill === 1, "window.CanvasRenderingContext2D.prototype.fill === 1");
|
ok(window.CanvasRenderingContext2D.prototype.fill === 1, "window.CanvasRenderingContext2D.prototype.fill === 1");
|
||||||
delete window.CanvasRenderingContext2D.prototype.fill;
|
delete window.CanvasRenderingContext2D.prototype.fill;
|
||||||
if (IsAzureEnabled()) {
|
ok(window.CanvasRenderingContext2D.prototype.fill === undefined, "window.CanvasRenderingContext2D.prototype.fill === undefined");
|
||||||
ok(window.CanvasRenderingContext2D.prototype.fill === undefined, "window.CanvasRenderingContext2D.prototype.fill === undefined");
|
|
||||||
} else {
|
|
||||||
todo(window.CanvasRenderingContext2D.prototype.fill === undefined, "window.CanvasRenderingContext2D.prototype.fill === undefined");
|
|
||||||
}
|
|
||||||
|
|
||||||
//restore the original method to ensure that other tests can run successfully
|
//restore the original method to ensure that other tests can run successfully
|
||||||
window.CanvasRenderingContext2D.prototype.fill = fill;
|
window.CanvasRenderingContext2D.prototype.fill = fill;
|
||||||
|
@ -73,11 +73,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile) = 0;
|
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile) = 0;
|
||||||
|
|
||||||
|
/* Called when the stream wants more data */
|
||||||
|
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime) = 0;
|
||||||
|
|
||||||
/* Stop the device and release the corresponding MediaStream */
|
/* Stop the device and release the corresponding MediaStream */
|
||||||
virtual nsresult Stop() = 0;
|
virtual nsresult Stop() = 0;
|
||||||
|
|
||||||
|
/* Return false if device is currently allocated or started */
|
||||||
|
bool IsAvailable() {
|
||||||
|
if (mState == kAllocated || mState == kStarted) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* It is an error to call Start() before an Allocate(), and Stop() before
|
/* It is an error to call Start() before an Allocate(), and Stop() before
|
||||||
* a Start(). Only Allocate() may be called after a Deallocate(). */
|
* a Start(). Only Allocate() may be called after a Deallocate(). */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MediaEngineState mState;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,8 +35,10 @@ const MediaEngineVideoOptions MediaEngineDefaultVideoSource::mOpts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MediaEngineDefaultVideoSource::MediaEngineDefaultVideoSource()
|
MediaEngineDefaultVideoSource::MediaEngineDefaultVideoSource()
|
||||||
: mTimer(nullptr), mState(kReleased)
|
: mTimer(nullptr)
|
||||||
{}
|
{
|
||||||
|
mState = kReleased;
|
||||||
|
}
|
||||||
|
|
||||||
MediaEngineDefaultVideoSource::~MediaEngineDefaultVideoSource()
|
MediaEngineDefaultVideoSource::~MediaEngineDefaultVideoSource()
|
||||||
{}
|
{}
|
||||||
@ -201,10 +203,35 @@ MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineDefaultAudioSource, nsITimerCallback)
|
void
|
||||||
|
MediaEngineDefaultVideoSource::NotifyPull(MediaStreamGraph* aGraph,
|
||||||
|
StreamTime aDesiredTime)
|
||||||
|
{
|
||||||
|
// Ignore - we push video data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default audio source.
|
* Default audio source.
|
||||||
*/
|
*/
|
||||||
|
NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineDefaultAudioSource, nsITimerCallback)
|
||||||
|
|
||||||
|
MediaEngineDefaultAudioSource::MediaEngineDefaultAudioSource()
|
||||||
|
: mTimer(nullptr)
|
||||||
|
{
|
||||||
|
mState = kReleased;
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaEngineDefaultAudioSource::~MediaEngineDefaultAudioSource()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaEngineDefaultAudioSource::NotifyPull(MediaStreamGraph* aGraph,
|
||||||
|
StreamTime aDesiredTime)
|
||||||
|
{
|
||||||
|
// Ignore - we push audio data
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineDefaultAudioSource::GetName(nsAString& aName)
|
MediaEngineDefaultAudioSource::GetName(nsAString& aName)
|
||||||
{
|
{
|
||||||
@ -312,13 +339,43 @@ MediaEngineDefaultAudioSource::Notify(nsITimer* aTimer)
|
|||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineDefault::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >* aVSources) {
|
MediaEngineDefault::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >* aVSources) {
|
||||||
aVSources->AppendElement(mVSource);
|
int32_t found = false;
|
||||||
|
int32_t len = mVSources.Length();
|
||||||
|
for (int32_t i = 0; i < len; i++) {
|
||||||
|
nsRefPtr<MediaEngineVideoSource> source = mVSources.ElementAt(i);
|
||||||
|
aVSources->AppendElement(source);
|
||||||
|
if (source->IsAvailable()) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All streams are currently busy, just make a new one.
|
||||||
|
if (!found) {
|
||||||
|
nsRefPtr<MediaEngineVideoSource> newSource =
|
||||||
|
new MediaEngineDefaultVideoSource();
|
||||||
|
mVSources.AppendElement(newSource);
|
||||||
|
aVSources->AppendElement(newSource);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineDefault::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >* aASources) {
|
MediaEngineDefault::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >* aASources) {
|
||||||
aASources->AppendElement(mASource);
|
int32_t len = mVSources.Length();
|
||||||
|
for (int32_t i = 0; i < len; i++) {
|
||||||
|
nsRefPtr<MediaEngineAudioSource> source = mASources.ElementAt(i);
|
||||||
|
if (source->IsAvailable()) {
|
||||||
|
aASources->AppendElement(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All streams are currently busy, just make a new one.
|
||||||
|
if (aASources->Length() == 0) {
|
||||||
|
nsRefPtr<MediaEngineAudioSource> newSource =
|
||||||
|
new MediaEngineDefaultAudioSource();
|
||||||
|
mASources.AppendElement(newSource);
|
||||||
|
aASources->AppendElement(newSource);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,11 +41,11 @@ public:
|
|||||||
|
|
||||||
virtual const MediaEngineVideoOptions *GetOptions();
|
virtual const MediaEngineVideoOptions *GetOptions();
|
||||||
virtual nsresult Allocate();
|
virtual nsresult Allocate();
|
||||||
|
|
||||||
virtual nsresult Deallocate();
|
virtual nsresult Deallocate();
|
||||||
virtual nsresult Start(SourceMediaStream*, TrackID);
|
virtual nsresult Start(SourceMediaStream*, TrackID);
|
||||||
virtual nsresult Stop();
|
virtual nsresult Stop();
|
||||||
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
|
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
|
||||||
|
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSITIMERCALLBACK
|
NS_DECL_NSITIMERCALLBACK
|
||||||
@ -60,7 +60,6 @@ protected:
|
|||||||
nsCOMPtr<nsITimer> mTimer;
|
nsCOMPtr<nsITimer> mTimer;
|
||||||
nsRefPtr<layers::ImageContainer> mImageContainer;
|
nsRefPtr<layers::ImageContainer> mImageContainer;
|
||||||
|
|
||||||
MediaEngineState mState;
|
|
||||||
SourceMediaStream* mSource;
|
SourceMediaStream* mSource;
|
||||||
layers::PlanarYCbCrImage* mImage;
|
layers::PlanarYCbCrImage* mImage;
|
||||||
static const MediaEngineVideoOptions mOpts;
|
static const MediaEngineVideoOptions mOpts;
|
||||||
@ -70,18 +69,18 @@ class MediaEngineDefaultAudioSource : public nsITimerCallback,
|
|||||||
public MediaEngineAudioSource
|
public MediaEngineAudioSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MediaEngineDefaultAudioSource() : mTimer(nullptr), mState(kReleased) {}
|
MediaEngineDefaultAudioSource();
|
||||||
~MediaEngineDefaultAudioSource(){};
|
~MediaEngineDefaultAudioSource();
|
||||||
|
|
||||||
virtual void GetName(nsAString&);
|
virtual void GetName(nsAString&);
|
||||||
virtual void GetUUID(nsAString&);
|
virtual void GetUUID(nsAString&);
|
||||||
|
|
||||||
virtual nsresult Allocate();
|
virtual nsresult Allocate();
|
||||||
|
|
||||||
virtual nsresult Deallocate();
|
virtual nsresult Deallocate();
|
||||||
virtual nsresult Start(SourceMediaStream*, TrackID);
|
virtual nsresult Start(SourceMediaStream*, TrackID);
|
||||||
virtual nsresult Stop();
|
virtual nsresult Stop();
|
||||||
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
|
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
|
||||||
|
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSITIMERCALLBACK
|
NS_DECL_NSITIMERCALLBACK
|
||||||
@ -90,25 +89,21 @@ protected:
|
|||||||
TrackID mTrackID;
|
TrackID mTrackID;
|
||||||
nsCOMPtr<nsITimer> mTimer;
|
nsCOMPtr<nsITimer> mTimer;
|
||||||
|
|
||||||
MediaEngineState mState;
|
|
||||||
SourceMediaStream* mSource;
|
SourceMediaStream* mSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MediaEngineDefault : public MediaEngine
|
class MediaEngineDefault : public MediaEngine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MediaEngineDefault() {
|
MediaEngineDefault() {}
|
||||||
mVSource = new MediaEngineDefaultVideoSource();
|
|
||||||
mASource = new MediaEngineDefaultAudioSource();
|
|
||||||
}
|
|
||||||
~MediaEngineDefault() {}
|
~MediaEngineDefault() {}
|
||||||
|
|
||||||
virtual void EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >*);
|
virtual void EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >*);
|
||||||
virtual void EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >*);
|
virtual void EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<MediaEngineVideoSource> mVSource;
|
nsTArray<nsRefPtr<MediaEngineVideoSource> > mVSources;
|
||||||
nsRefPtr<MediaEngineAudioSource> mASource;
|
nsTArray<nsRefPtr<MediaEngineAudioSource> > mASources;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,13 +53,20 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We still enumerate every time, in case a new device was plugged in since
|
||||||
|
* the last call. TODO: Verify that WebRTC actually does deal with hotplugging
|
||||||
|
* new devices (with or without new engine creation) and accordingly adjust.
|
||||||
|
* Enumeration is not neccessary if GIPS reports the same set of devices
|
||||||
|
* for a given instance of the engine. Likewise, if a device was plugged out,
|
||||||
|
* mVideoSources must be updated.
|
||||||
|
*/
|
||||||
int num = ptrViECapture->NumberOfCaptureDevices();
|
int num = ptrViECapture->NumberOfCaptureDevices();
|
||||||
if (num <= 0) {
|
if (num <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
#ifdef DEBUG
|
|
||||||
const unsigned int kMaxDeviceNameLength = 128; // XXX FIX!
|
const unsigned int kMaxDeviceNameLength = 128; // XXX FIX!
|
||||||
const unsigned int kMaxUniqueIdLength = 256;
|
const unsigned int kMaxUniqueIdLength = 256;
|
||||||
char deviceName[kMaxDeviceNameLength];
|
char deviceName[kMaxDeviceNameLength];
|
||||||
@ -71,8 +78,10 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
|
|||||||
int error = ptrViECapture->GetCaptureDevice(i, deviceName,
|
int error = ptrViECapture->GetCaptureDevice(i, deviceName,
|
||||||
sizeof(deviceName), uniqueId,
|
sizeof(deviceName), uniqueId,
|
||||||
sizeof(uniqueId));
|
sizeof(uniqueId));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG((" VieCapture:GetCaptureDevice: Failed %d",
|
LOG((" VieCapture:GetCaptureDevice: Failed %d",
|
||||||
ptrViEBase->LastError() ));
|
ptrViEBase->LastError() ));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -82,7 +91,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
|
|||||||
int numCaps = ptrViECapture->NumberOfCapabilities(uniqueId, kMaxUniqueIdLength);
|
int numCaps = ptrViECapture->NumberOfCapabilities(uniqueId, kMaxUniqueIdLength);
|
||||||
LOG(("Number of Capabilities %d", numCaps));
|
LOG(("Number of Capabilities %d", numCaps));
|
||||||
for (int j = 0; j < numCaps; j++) {
|
for (int j = 0; j < numCaps; j++) {
|
||||||
if (ptrViECapture->GetCaptureCapability(uniqueId, kMaxUniqueIdLength,
|
if (ptrViECapture->GetCaptureCapability(uniqueId, kMaxUniqueIdLength,
|
||||||
j, cap ) != 0 ) {
|
j, cap ) != 0 ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -91,8 +100,16 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsRefPtr<MediaEngineVideoSource> vSource = new MediaEngineWebRTCVideoSource(mVideoEngine, i);
|
nsRefPtr<MediaEngineWebRTCVideoSource> vSource;
|
||||||
aVSources->AppendElement(vSource.forget());
|
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
||||||
|
if (mVideoSources.Get(uuid, getter_AddRefs(vSource))) {
|
||||||
|
// We've already seen this device, just append.
|
||||||
|
aVSources->AppendElement(vSource.get());
|
||||||
|
} else {
|
||||||
|
vSource = new MediaEngineWebRTCVideoSource(mVideoEngine, i);
|
||||||
|
mVideoSources.Put(uuid, vSource); // Hashtable takes ownership.
|
||||||
|
aVSources->AppendElement(vSource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrViEBase->Release();
|
ptrViEBase->Release();
|
||||||
@ -136,31 +153,41 @@ MediaEngineWebRTC::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSourc
|
|||||||
for (int i = 0; i < nDevices; i++) {
|
for (int i = 0; i < nDevices; i++) {
|
||||||
// We use constants here because GetRecordingDeviceName takes char[128].
|
// We use constants here because GetRecordingDeviceName takes char[128].
|
||||||
char deviceName[128];
|
char deviceName[128];
|
||||||
char uniqueID[128];
|
char uniqueId[128];
|
||||||
// paranoia; jingle doesn't bother with this
|
// paranoia; jingle doesn't bother with this
|
||||||
deviceName[0] = '\0';
|
deviceName[0] = '\0';
|
||||||
uniqueID[0] = '\0';
|
uniqueId[0] = '\0';
|
||||||
|
|
||||||
ptrVoEHw->GetRecordingDeviceName(i, deviceName, uniqueID);
|
ptrVoEHw->GetRecordingDeviceName(i, deviceName, uniqueId);
|
||||||
nsRefPtr<MediaEngineAudioSource> aSource = new MediaEngineWebRTCAudioSource(
|
|
||||||
mVoiceEngine, i, deviceName, uniqueID
|
nsRefPtr<MediaEngineWebRTCAudioSource> aSource;
|
||||||
);
|
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
||||||
aASources->AppendElement(aSource.forget());
|
if (mAudioSources.Get(uuid, getter_AddRefs(aSource))) {
|
||||||
|
// We've already seen this device, just append.
|
||||||
|
aASources->AppendElement(aSource.get());
|
||||||
|
} else {
|
||||||
|
aSource = new MediaEngineWebRTCAudioSource(
|
||||||
|
mVoiceEngine, i, deviceName, uniqueId
|
||||||
|
);
|
||||||
|
mAudioSources.Put(uuid, aSource); // Hashtable takes ownership.
|
||||||
|
aASources->AppendElement(aSource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrVoEHw->Release();
|
ptrVoEHw->Release();
|
||||||
ptrVoEBase->Release();
|
ptrVoEBase->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineWebRTC::Shutdown()
|
MediaEngineWebRTC::Shutdown()
|
||||||
{
|
{
|
||||||
if (mVideoEngine) {
|
if (mVideoEngine) {
|
||||||
|
mVideoSources.Clear();
|
||||||
webrtc::VideoEngine::Delete(mVideoEngine);
|
webrtc::VideoEngine::Delete(mVideoEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mVoiceEngine) {
|
if (mVoiceEngine) {
|
||||||
|
mAudioSources.Clear();
|
||||||
webrtc::VoiceEngine::Delete(mVoiceEngine);
|
webrtc::VoiceEngine::Delete(mVoiceEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,16 +53,31 @@ class MediaEngineWebRTCVideoSource : public MediaEngineVideoSource,
|
|||||||
public nsRunnable
|
public nsRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const int DEFAULT_VIDEO_FPS = 30;
|
static const int DEFAULT_VIDEO_FPS = 60;
|
||||||
static const int DEFAULT_MIN_VIDEO_FPS = 10;
|
static const int DEFAULT_MIN_VIDEO_FPS = 10;
|
||||||
|
|
||||||
// ViEExternalRenderer.
|
// ViEExternalRenderer.
|
||||||
virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int);
|
virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int);
|
||||||
virtual int DeliverFrame(unsigned char*, int, uint32_t, int64_t);
|
virtual int DeliverFrame(unsigned char*, int, uint32_t, int64_t);
|
||||||
|
|
||||||
MediaEngineWebRTCVideoSource(webrtc::VideoEngine* videoEnginePtr,
|
MediaEngineWebRTCVideoSource(webrtc::VideoEngine* aVideoEnginePtr,
|
||||||
int index, int aMinFps = DEFAULT_MIN_VIDEO_FPS);
|
int aIndex, int aMinFps = DEFAULT_MIN_VIDEO_FPS)
|
||||||
~MediaEngineWebRTCVideoSource();
|
: mVideoEngine(aVideoEnginePtr)
|
||||||
|
, mCaptureIndex(aIndex)
|
||||||
|
, mCapabilityChosen(false)
|
||||||
|
, mWidth(640)
|
||||||
|
, mHeight(480)
|
||||||
|
, mLastEndTime(0)
|
||||||
|
, mMonitor("WebRTCCamera.Monitor")
|
||||||
|
, mFps(DEFAULT_VIDEO_FPS)
|
||||||
|
, mMinFps(aMinFps)
|
||||||
|
, mInitDone(false)
|
||||||
|
, mInSnapshotMode(false)
|
||||||
|
, mSnapshotPath(NULL) {
|
||||||
|
mState = kReleased;
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
~MediaEngineWebRTCVideoSource() { Shutdown(); }
|
||||||
|
|
||||||
virtual void GetName(nsAString&);
|
virtual void GetName(nsAString&);
|
||||||
virtual void GetUUID(nsAString&);
|
virtual void GetUUID(nsAString&);
|
||||||
@ -72,6 +87,7 @@ public:
|
|||||||
virtual nsresult Start(SourceMediaStream*, TrackID);
|
virtual nsresult Start(SourceMediaStream*, TrackID);
|
||||||
virtual nsresult Stop();
|
virtual nsresult Stop();
|
||||||
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
|
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
|
||||||
|
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
@ -114,8 +130,8 @@ private:
|
|||||||
bool mCapabilityChosen;
|
bool mCapabilityChosen;
|
||||||
int mWidth, mHeight;
|
int mWidth, mHeight;
|
||||||
TrackID mTrackID;
|
TrackID mTrackID;
|
||||||
|
TrackTicks mLastEndTime;
|
||||||
|
|
||||||
MediaEngineState mState;
|
|
||||||
mozilla::ReentrantMonitor mMonitor; // Monitor for processing WebRTC frames.
|
mozilla::ReentrantMonitor mMonitor; // Monitor for processing WebRTC frames.
|
||||||
SourceMediaStream* mSource;
|
SourceMediaStream* mSource;
|
||||||
|
|
||||||
@ -125,6 +141,7 @@ private:
|
|||||||
bool mInSnapshotMode;
|
bool mInSnapshotMode;
|
||||||
nsString* mSnapshotPath;
|
nsString* mSnapshotPath;
|
||||||
|
|
||||||
|
nsRefPtr<layers::Image> mImage;
|
||||||
nsRefPtr<layers::ImageContainer> mImageContainer;
|
nsRefPtr<layers::ImageContainer> mImageContainer;
|
||||||
|
|
||||||
PRLock* mSnapshotLock;
|
PRLock* mSnapshotLock;
|
||||||
@ -148,15 +165,12 @@ public:
|
|||||||
, mMonitor("WebRTCMic.Monitor")
|
, mMonitor("WebRTCMic.Monitor")
|
||||||
, mCapIndex(aIndex)
|
, mCapIndex(aIndex)
|
||||||
, mChannel(-1)
|
, mChannel(-1)
|
||||||
, mInitDone(false)
|
, mInitDone(false) {
|
||||||
, mState(kReleased) {
|
mState = kReleased;
|
||||||
|
|
||||||
mVoEBase = webrtc::VoEBase::GetInterface(mVoiceEngine);
|
|
||||||
mDeviceName.Assign(NS_ConvertUTF8toUTF16(name));
|
mDeviceName.Assign(NS_ConvertUTF8toUTF16(name));
|
||||||
mDeviceUUID.Assign(NS_ConvertUTF8toUTF16(uuid));
|
mDeviceUUID.Assign(NS_ConvertUTF8toUTF16(uuid));
|
||||||
mInitDone = true;
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
~MediaEngineWebRTCAudioSource() { Shutdown(); }
|
~MediaEngineWebRTCAudioSource() { Shutdown(); }
|
||||||
|
|
||||||
virtual void GetName(nsAString&);
|
virtual void GetName(nsAString&);
|
||||||
@ -167,6 +181,7 @@ public:
|
|||||||
virtual nsresult Start(SourceMediaStream*, TrackID);
|
virtual nsresult Start(SourceMediaStream*, TrackID);
|
||||||
virtual nsresult Stop();
|
virtual nsresult Stop();
|
||||||
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
|
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
|
||||||
|
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
|
||||||
|
|
||||||
// VoEMediaProcess.
|
// VoEMediaProcess.
|
||||||
void Process(const int channel, const webrtc::ProcessingTypes type,
|
void Process(const int channel, const webrtc::ProcessingTypes type,
|
||||||
@ -192,7 +207,6 @@ private:
|
|||||||
int mChannel;
|
int mChannel;
|
||||||
TrackID mTrackID;
|
TrackID mTrackID;
|
||||||
bool mInitDone;
|
bool mInitDone;
|
||||||
MediaEngineState mState;
|
|
||||||
|
|
||||||
nsString mDeviceName;
|
nsString mDeviceName;
|
||||||
nsString mDeviceUUID;
|
nsString mDeviceUUID;
|
||||||
@ -207,8 +221,10 @@ public:
|
|||||||
: mVideoEngine(NULL)
|
: mVideoEngine(NULL)
|
||||||
, mVoiceEngine(NULL)
|
, mVoiceEngine(NULL)
|
||||||
, mVideoEngineInit(false)
|
, mVideoEngineInit(false)
|
||||||
, mAudioEngineInit(false) {}
|
, mAudioEngineInit(false) {
|
||||||
|
mVideoSources.Init();
|
||||||
|
mAudioSources.Init();
|
||||||
|
}
|
||||||
~MediaEngineWebRTC() { Shutdown(); }
|
~MediaEngineWebRTC() { Shutdown(); }
|
||||||
|
|
||||||
// Clients should ensure to clean-up sources video/audio sources
|
// Clients should ensure to clean-up sources video/audio sources
|
||||||
@ -225,6 +241,11 @@ private:
|
|||||||
// Need this to avoid unneccesary WebRTC calls while enumerating.
|
// Need this to avoid unneccesary WebRTC calls while enumerating.
|
||||||
bool mVideoEngineInit;
|
bool mVideoEngineInit;
|
||||||
bool mAudioEngineInit;
|
bool mAudioEngineInit;
|
||||||
|
|
||||||
|
// Store devices we've already seen in a hashtable for quick return.
|
||||||
|
// Maps UUID to MediaEngineSource (one set for audio, one for video).
|
||||||
|
nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCVideoSource > mVideoSources;
|
||||||
|
nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCAudioSource > mAudioSources;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,49 +53,6 @@ MediaEngineWebRTCAudioSource::Allocate()
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mVoEBase->Init();
|
|
||||||
|
|
||||||
mVoERender = webrtc::VoEExternalMedia::GetInterface(mVoiceEngine);
|
|
||||||
if (!mVoERender) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mChannel = mVoEBase->CreateChannel();
|
|
||||||
if (mChannel < 0) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for availability.
|
|
||||||
webrtc::VoEHardware* ptrVoEHw = webrtc::VoEHardware::GetInterface(mVoiceEngine);
|
|
||||||
if (ptrVoEHw->SetRecordingDevice(mCapIndex)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool avail = false;
|
|
||||||
ptrVoEHw->GetRecordingDeviceStatus(avail);
|
|
||||||
if (!avail) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set "codec" to PCM, 32kHz on 1 channel
|
|
||||||
webrtc::VoECodec* ptrVoECodec;
|
|
||||||
webrtc::CodecInst codec;
|
|
||||||
ptrVoECodec = webrtc::VoECodec::GetInterface(mVoiceEngine);
|
|
||||||
if (!ptrVoECodec) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(codec.plname, ENCODING);
|
|
||||||
codec.channels = CHANNELS;
|
|
||||||
codec.rate = SAMPLE_RATE;
|
|
||||||
codec.plfreq = SAMPLE_FREQUENCY;
|
|
||||||
codec.pacsize = SAMPLE_LENGTH;
|
|
||||||
codec.pltype = 0; // Default payload type
|
|
||||||
|
|
||||||
if (ptrVoECodec->SetSendCodec(mChannel, codec)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Audio doesn't play through unless we set a receiver and destination, so
|
// Audio doesn't play through unless we set a receiver and destination, so
|
||||||
// we setup a dummy local destination, and do a loopback.
|
// we setup a dummy local destination, and do a loopback.
|
||||||
mVoEBase->SetLocalReceiver(mChannel, DEFAULT_PORT);
|
mVoEBase->SetLocalReceiver(mChannel, DEFAULT_PORT);
|
||||||
@ -112,9 +69,6 @@ MediaEngineWebRTCAudioSource::Deallocate()
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mVoEBase->Terminate();
|
|
||||||
mVoERender->Release();
|
|
||||||
|
|
||||||
mState = kReleased;
|
mState = kReleased;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -135,6 +89,7 @@ MediaEngineWebRTCAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
|
|||||||
segment->Init(CHANNELS);
|
segment->Init(CHANNELS);
|
||||||
mSource->AddTrack(aID, SAMPLE_FREQUENCY, 0, segment);
|
mSource->AddTrack(aID, SAMPLE_FREQUENCY, 0, segment);
|
||||||
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
||||||
|
LOG(("Initial audio"));
|
||||||
mTrackID = aID;
|
mTrackID = aID;
|
||||||
|
|
||||||
if (mVoEBase->StartReceive(mChannel)) {
|
if (mVoEBase->StartReceive(mChannel)) {
|
||||||
@ -174,12 +129,69 @@ MediaEngineWebRTCAudioSource::Stop()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaEngineWebRTCAudioSource::NotifyPull(MediaStreamGraph* aGraph,
|
||||||
|
StreamTime aDesiredTime)
|
||||||
|
{
|
||||||
|
// Ignore - we push audio data
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
MediaEngineWebRTCAudioSource::Snapshot(uint32_t aDuration, nsIDOMFile** aFile)
|
MediaEngineWebRTCAudioSource::Snapshot(uint32_t aDuration, nsIDOMFile** aFile)
|
||||||
{
|
{
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaEngineWebRTCAudioSource::Init()
|
||||||
|
{
|
||||||
|
mVoEBase = webrtc::VoEBase::GetInterface(mVoiceEngine);
|
||||||
|
|
||||||
|
mVoEBase->Init();
|
||||||
|
|
||||||
|
mVoERender = webrtc::VoEExternalMedia::GetInterface(mVoiceEngine);
|
||||||
|
if (!mVoERender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mChannel = mVoEBase->CreateChannel();
|
||||||
|
if (mChannel < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for availability.
|
||||||
|
webrtc::VoEHardware* ptrVoEHw = webrtc::VoEHardware::GetInterface(mVoiceEngine);
|
||||||
|
if (ptrVoEHw->SetRecordingDevice(mCapIndex)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool avail = false;
|
||||||
|
ptrVoEHw->GetRecordingDeviceStatus(avail);
|
||||||
|
if (!avail) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set "codec" to PCM, 32kHz on 1 channel
|
||||||
|
webrtc::VoECodec* ptrVoECodec;
|
||||||
|
webrtc::CodecInst codec;
|
||||||
|
ptrVoECodec = webrtc::VoECodec::GetInterface(mVoiceEngine);
|
||||||
|
if (!ptrVoECodec) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(codec.plname, ENCODING);
|
||||||
|
codec.channels = CHANNELS;
|
||||||
|
codec.rate = SAMPLE_RATE;
|
||||||
|
codec.plfreq = SAMPLE_FREQUENCY;
|
||||||
|
codec.pacsize = SAMPLE_LENGTH;
|
||||||
|
codec.pltype = 0; // Default payload type
|
||||||
|
|
||||||
|
if (ptrVoECodec->SetSendCodec(mChannel, codec)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mInitDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineWebRTCAudioSource::Shutdown()
|
MediaEngineWebRTCAudioSource::Shutdown()
|
||||||
@ -196,6 +208,8 @@ MediaEngineWebRTCAudioSource::Shutdown()
|
|||||||
Deallocate();
|
Deallocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mVoEBase->Terminate();
|
||||||
|
mVoERender->Release();
|
||||||
mVoEBase->Release();
|
mVoEBase->Release();
|
||||||
|
|
||||||
mState = kReleased;
|
mState = kReleased;
|
||||||
|
@ -21,29 +21,6 @@ extern PRLogModuleInfo* gMediaManagerLog;
|
|||||||
*/
|
*/
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineWebRTCVideoSource, nsIRunnable)
|
NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineWebRTCVideoSource, nsIRunnable)
|
||||||
|
|
||||||
MediaEngineWebRTCVideoSource::MediaEngineWebRTCVideoSource(webrtc::VideoEngine* aVideoEnginePtr,
|
|
||||||
int aIndex, int aMinFps)
|
|
||||||
: mVideoEngine(aVideoEnginePtr)
|
|
||||||
, mCaptureIndex(aIndex)
|
|
||||||
, mCapabilityChosen(false)
|
|
||||||
, mWidth(640)
|
|
||||||
, mHeight(480)
|
|
||||||
, mState(kReleased)
|
|
||||||
, mMonitor("WebRTCCamera.Monitor")
|
|
||||||
, mFps(DEFAULT_VIDEO_FPS)
|
|
||||||
, mMinFps(aMinFps)
|
|
||||||
, mInitDone(false)
|
|
||||||
, mInSnapshotMode(false)
|
|
||||||
, mSnapshotPath(NULL)
|
|
||||||
{
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaEngineWebRTCVideoSource::~MediaEngineWebRTCVideoSource()
|
|
||||||
{
|
|
||||||
Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ViEExternalRenderer Callback.
|
// ViEExternalRenderer Callback.
|
||||||
int
|
int
|
||||||
MediaEngineWebRTCVideoSource::FrameSizeChange(
|
MediaEngineWebRTCVideoSource::FrameSizeChange(
|
||||||
@ -59,8 +36,6 @@ int
|
|||||||
MediaEngineWebRTCVideoSource::DeliverFrame(
|
MediaEngineWebRTCVideoSource::DeliverFrame(
|
||||||
unsigned char* buffer, int size, uint32_t time_stamp, int64_t render_time)
|
unsigned char* buffer, int size, uint32_t time_stamp, int64_t render_time)
|
||||||
{
|
{
|
||||||
ReentrantMonitorAutoEnter enter(mMonitor);
|
|
||||||
|
|
||||||
if (mInSnapshotMode) {
|
if (mInSnapshotMode) {
|
||||||
// Set the condition variable to false and notify Snapshot().
|
// Set the condition variable to false and notify Snapshot().
|
||||||
PR_Lock(mSnapshotLock);
|
PR_Lock(mSnapshotLock);
|
||||||
@ -78,6 +53,7 @@ MediaEngineWebRTCVideoSource::DeliverFrame(
|
|||||||
|
|
||||||
// Create a video frame and append it to the track.
|
// Create a video frame and append it to the track.
|
||||||
ImageFormat format = PLANAR_YCBCR;
|
ImageFormat format = PLANAR_YCBCR;
|
||||||
|
|
||||||
nsRefPtr<layers::Image> image = mImageContainer->CreateImage(&format, 1);
|
nsRefPtr<layers::Image> image = mImageContainer->CreateImage(&format, 1);
|
||||||
|
|
||||||
layers::PlanarYCbCrImage* videoImage = static_cast<layers::PlanarYCbCrImage*>(image.get());
|
layers::PlanarYCbCrImage* videoImage = static_cast<layers::PlanarYCbCrImage*>(image.get());
|
||||||
@ -101,12 +77,48 @@ MediaEngineWebRTCVideoSource::DeliverFrame(
|
|||||||
|
|
||||||
videoImage->SetData(data);
|
videoImage->SetData(data);
|
||||||
|
|
||||||
VideoSegment segment;
|
#ifdef LOG_ALL_FRAMES
|
||||||
segment.AppendFrame(image.forget(), 1, gfxIntSize(mWidth, mHeight));
|
static uint32_t frame_num = 0;
|
||||||
mSource->AppendToTrack(mTrackID, &(segment));
|
LOG(("frame %d; timestamp %u, render_time %lu", frame_num++, time_stamp, render_time));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// we don't touch anything in 'this' until here (except for snapshot,
|
||||||
|
// which has it's own lock)
|
||||||
|
ReentrantMonitorAutoEnter enter(mMonitor);
|
||||||
|
|
||||||
|
// implicitly releases last image
|
||||||
|
mImage = image.forget();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called if the graph thinks it's running out of buffered video; repeat
|
||||||
|
// the last frame for whatever minimum period it think it needs. Note that
|
||||||
|
// this means that no *real* frame can be inserted during this period.
|
||||||
|
void
|
||||||
|
MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph,
|
||||||
|
StreamTime aDesiredTime)
|
||||||
|
{
|
||||||
|
VideoSegment segment;
|
||||||
|
|
||||||
|
ReentrantMonitorAutoEnter enter(mMonitor);
|
||||||
|
|
||||||
|
if (mState != kStarted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Note: we're not giving up mImage here
|
||||||
|
nsRefPtr<layers::Image> image = mImage;
|
||||||
|
TrackTicks target = TimeToTicksRoundUp(USECS_PER_S, aDesiredTime);
|
||||||
|
TrackTicks delta = target - mLastEndTime;
|
||||||
|
#ifdef LOG_ALL_FRAMES
|
||||||
|
LOG(("NotifyPull, target = %lu, delta = %lu", (uint64_t) target, (uint64_t) delta));
|
||||||
|
#endif
|
||||||
|
// NULL images are allowed
|
||||||
|
segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
|
||||||
|
mSource->AppendToTrack(mTrackID, &(segment));
|
||||||
|
mLastEndTime = target;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineWebRTCVideoSource::ChooseCapability(uint32_t aWidth, uint32_t aHeight, uint32_t aMinFPS)
|
MediaEngineWebRTCVideoSource::ChooseCapability(uint32_t aWidth, uint32_t aHeight, uint32_t aMinFPS)
|
||||||
{
|
{
|
||||||
@ -191,10 +203,6 @@ MediaEngineWebRTCVideoSource::Allocate()
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mViECapture->StartCapture(mCaptureIndex, mCapability) < 0) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mState = kAllocated;
|
mState = kAllocated;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -206,7 +214,6 @@ MediaEngineWebRTCVideoSource::Deallocate()
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mViECapture->StopCapture(mCaptureIndex);
|
|
||||||
mViECapture->ReleaseCaptureDevice(mCaptureIndex);
|
mViECapture->ReleaseCaptureDevice(mCaptureIndex);
|
||||||
mState = kReleased;
|
mState = kReleased;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -241,8 +248,10 @@ MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
|
|||||||
mTrackID = aID;
|
mTrackID = aID;
|
||||||
|
|
||||||
mImageContainer = layers::LayerManager::CreateImageContainer();
|
mImageContainer = layers::LayerManager::CreateImageContainer();
|
||||||
mSource->AddTrack(aID, mFps, 0, new VideoSegment());
|
|
||||||
|
mSource->AddTrack(aID, USECS_PER_S, 0, new VideoSegment());
|
||||||
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
||||||
|
mLastEndTime = 0;
|
||||||
|
|
||||||
error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
|
error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
|
||||||
if (error == -1) {
|
if (error == -1) {
|
||||||
@ -254,6 +263,10 @@ MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mViECapture->StartCapture(mCaptureIndex, mCapability) < 0) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
mState = kStarted;
|
mState = kStarted;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -270,6 +283,7 @@ MediaEngineWebRTCVideoSource::Stop()
|
|||||||
|
|
||||||
mViERender->StopRender(mCaptureIndex);
|
mViERender->StopRender(mCaptureIndex);
|
||||||
mViERender->RemoveRenderer(mCaptureIndex);
|
mViERender->RemoveRenderer(mCaptureIndex);
|
||||||
|
mViECapture->StopCapture(mCaptureIndex);
|
||||||
|
|
||||||
mState = kStopped;
|
mState = kStopped;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
This is sqlite 3.7.14
|
This is sqlite 3.7.14.1
|
||||||
|
|
||||||
-- Ryan VanderMeulen <ryanvm@gmail.com>, 09/2012
|
-- Ryan VanderMeulen <ryanvm@gmail.com>, 10/2012
|
||||||
|
|
||||||
See http://www.sqlite.org/ for more info.
|
See http://www.sqlite.org/ for more info.
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
** This file is an amalgamation of many separate C source files from SQLite
|
** This file is an amalgamation of many separate C source files from SQLite
|
||||||
** version 3.7.14. By combining all the individual C code files into this
|
** version 3.7.14.1. By combining all the individual C code files into this
|
||||||
** single large file, the entire code can be compiled as a single translation
|
** single large file, the entire code can be compiled as a single translation
|
||||||
** unit. This allows many compilers to do optimizations that would not be
|
** unit. This allows many compilers to do optimizations that would not be
|
||||||
** possible if the files were compiled separately. Performance improvements
|
** possible if the files were compiled separately. Performance improvements
|
||||||
@ -673,9 +673,9 @@ extern "C" {
|
|||||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||||
** [sqlite_version()] and [sqlite_source_id()].
|
** [sqlite_version()] and [sqlite_source_id()].
|
||||||
*/
|
*/
|
||||||
#define SQLITE_VERSION "3.7.14"
|
#define SQLITE_VERSION "3.7.14.1"
|
||||||
#define SQLITE_VERSION_NUMBER 3007014
|
#define SQLITE_VERSION_NUMBER 3007014
|
||||||
#define SQLITE_SOURCE_ID "2012-09-03 15:42:36 c0d89d4a9752922f9e367362366efde4f1b06f2a"
|
#define SQLITE_SOURCE_ID "2012-10-04 19:37:12 091570e46d04e84b67228e0bdbcd6e1fb60c6bdb"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Run-Time Library Version Numbers
|
** CAPI3REF: Run-Time Library Version Numbers
|
||||||
@ -53849,6 +53849,9 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
|
|||||||
** If aOvflSpace is set to a null pointer, this function returns
|
** If aOvflSpace is set to a null pointer, this function returns
|
||||||
** SQLITE_NOMEM.
|
** SQLITE_NOMEM.
|
||||||
*/
|
*/
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
||||||
|
#pragma optimize("", off)
|
||||||
|
#endif
|
||||||
static int balance_nonroot(
|
static int balance_nonroot(
|
||||||
MemPage *pParent, /* Parent page of siblings being balanced */
|
MemPage *pParent, /* Parent page of siblings being balanced */
|
||||||
int iParentIdx, /* Index of "the page" in pParent */
|
int iParentIdx, /* Index of "the page" in pParent */
|
||||||
@ -54479,6 +54482,9 @@ balance_cleanup:
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
||||||
|
#pragma optimize("", on)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -106086,7 +106092,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pLevel->u.pCovidx = pCov;
|
pLevel->u.pCovidx = pCov;
|
||||||
pLevel->iIdxCur = iCovCur;
|
if( pCov ) pLevel->iIdxCur = iCovCur;
|
||||||
if( pAndExpr ){
|
if( pAndExpr ){
|
||||||
pAndExpr->pLeft = 0;
|
pAndExpr->pLeft = 0;
|
||||||
sqlite3ExprDelete(pParse->db, pAndExpr);
|
sqlite3ExprDelete(pParse->db, pAndExpr);
|
||||||
|
@ -107,9 +107,9 @@ extern "C" {
|
|||||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||||
** [sqlite_version()] and [sqlite_source_id()].
|
** [sqlite_version()] and [sqlite_source_id()].
|
||||||
*/
|
*/
|
||||||
#define SQLITE_VERSION "3.7.14"
|
#define SQLITE_VERSION "3.7.14.1"
|
||||||
#define SQLITE_VERSION_NUMBER 3007014
|
#define SQLITE_VERSION_NUMBER 3007014
|
||||||
#define SQLITE_SOURCE_ID "2012-09-03 15:42:36 c0d89d4a9752922f9e367362366efde4f1b06f2a"
|
#define SQLITE_SOURCE_ID "2012-10-04 19:37:12 091570e46d04e84b67228e0bdbcd6e1fb60c6bdb"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Run-Time Library Version Numbers
|
** CAPI3REF: Run-Time Library Version Numbers
|
||||||
|
@ -4933,6 +4933,23 @@ nsDocShell::Destroy()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDocShell::GetUnscaledDevicePixelsPerCSSPixel(double *aScale)
|
||||||
|
{
|
||||||
|
if (mParentWidget) {
|
||||||
|
*aScale = mParentWidget->GetDefaultScale();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIBaseWindow> ownerWindow(do_QueryInterface(mTreeOwner));
|
||||||
|
if (ownerWindow) {
|
||||||
|
return ownerWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
*aScale = 1.0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocShell::SetPosition(int32_t x, int32_t y)
|
nsDocShell::SetPosition(int32_t x, int32_t y)
|
||||||
{
|
{
|
||||||
@ -4990,6 +5007,13 @@ NS_IMETHODIMP
|
|||||||
nsDocShell::GetPositionAndSize(int32_t * x, int32_t * y, int32_t * cx,
|
nsDocShell::GetPositionAndSize(int32_t * x, int32_t * y, int32_t * cx,
|
||||||
int32_t * cy)
|
int32_t * cy)
|
||||||
{
|
{
|
||||||
|
if (mParentWidget) {
|
||||||
|
// ensure size is up-to-date if window has changed resolution
|
||||||
|
nsIntRect r;
|
||||||
|
mParentWidget->GetClientBounds(r);
|
||||||
|
SetPositionAndSize(mBounds.x, mBounds.y, r.width, r.height, false);
|
||||||
|
}
|
||||||
|
|
||||||
// We should really consider just getting this information from
|
// We should really consider just getting this information from
|
||||||
// our window instead of duplicating the storage and code...
|
// our window instead of duplicating the storage and code...
|
||||||
if (cx || cy) {
|
if (cx || cy) {
|
||||||
|
@ -27,7 +27,7 @@ static mozilla::RefPtr<BluetoothOppManager> sInstance;
|
|||||||
static nsCOMPtr<nsIInputStream> stream = nullptr;
|
static nsCOMPtr<nsIInputStream> stream = nullptr;
|
||||||
static uint32_t sSentFileLength = 0;
|
static uint32_t sSentFileLength = 0;
|
||||||
static nsString sFileName;
|
static nsString sFileName;
|
||||||
static uint64_t sFileLength = 0;
|
static uint32_t sFileLength = 0;
|
||||||
static nsString sContentType;
|
static nsString sContentType;
|
||||||
static int sUpdateProgressCounter = 0;
|
static int sUpdateProgressCounter = 0;
|
||||||
|
|
||||||
@ -98,6 +98,8 @@ BluetoothOppManager::BluetoothOppManager() : mConnected(false)
|
|||||||
, mAbortFlag(false)
|
, mAbortFlag(false)
|
||||||
, mReadFileThread(nullptr)
|
, mReadFileThread(nullptr)
|
||||||
, mPacketLeftLength(0)
|
, mPacketLeftLength(0)
|
||||||
|
, mReceiving(false)
|
||||||
|
, mPutFinal(false)
|
||||||
{
|
{
|
||||||
// FIXME / Bug 800249:
|
// FIXME / Bug 800249:
|
||||||
// mConnectedDeviceAddress is Bluetooth address of connected device,
|
// mConnectedDeviceAddress is Bluetooth address of connected device,
|
||||||
@ -222,7 +224,7 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
int receivedLength = aMessage->mSize;
|
int receivedLength = aMessage->mSize;
|
||||||
|
|
||||||
if (mPacketLeftLength > 0) {
|
if (mPacketLeftLength > 0) {
|
||||||
opCode = ObexRequestCode::Put;
|
opCode = mPutFinal ? ObexRequestCode::PutFinal : ObexRequestCode::Put;
|
||||||
packetLength = mPacketLeftLength;
|
packetLength = mPacketLeftLength;
|
||||||
} else {
|
} else {
|
||||||
opCode = aMessage->mData[0];
|
opCode = aMessage->mData[0];
|
||||||
@ -254,18 +256,32 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
sFileName.AssignLiteral("Unknown");
|
sFileName.AssignLiteral("Unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = mBlob->GetSize(&sFileLength);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Can't get file size");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = mBlob->GetType(sContentType);
|
rv = mBlob->GetType(sContentType);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_WARNING("Can't get content type");
|
NS_WARNING("Can't get content type");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t fileLength;
|
||||||
|
rv = mBlob->GetSize(&fileLength);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Can't get file size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Currently we keep the size of files which were sent/received via
|
||||||
|
// Bluetooth not exceed UINT32_MAX because the Length header in OBEX
|
||||||
|
// is only 4-byte long. Although it is possible to transfer a file
|
||||||
|
// larger than UINT32_MAX, it needs to parse another OBEX Header
|
||||||
|
// and I would like to leave it as a feature.
|
||||||
|
if (fileLength <= UINT32_MAX) {
|
||||||
|
NS_WARNING("The file size is too large for now");
|
||||||
|
SendDisconnectRequest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sFileLength = fileLength;
|
||||||
|
|
||||||
if (NS_FAILED(NS_NewThread(getter_AddRefs(mReadFileThread)))) {
|
if (NS_FAILED(NS_NewThread(getter_AddRefs(mReadFileThread)))) {
|
||||||
NS_WARNING("Can't create thread");
|
NS_WARNING("Can't create thread");
|
||||||
SendDisconnectRequest();
|
SendDisconnectRequest();
|
||||||
@ -286,6 +302,7 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
NS_WARNING("[OPP] Disconnect failed");
|
NS_WARNING("[OPP] Disconnect failed");
|
||||||
} else {
|
} else {
|
||||||
mConnected = false;
|
mConnected = false;
|
||||||
|
mReceiving = false;
|
||||||
mLastCommand = 0;
|
mLastCommand = 0;
|
||||||
mBlob = nullptr;
|
mBlob = nullptr;
|
||||||
mReadFileThread = nullptr;
|
mReadFileThread = nullptr;
|
||||||
@ -330,35 +347,53 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||||||
SendDisconnectRequest();
|
SendDisconnectRequest();
|
||||||
} else {
|
} else {
|
||||||
// Remote request or unknown mLastCommand
|
// Remote request or unknown mLastCommand
|
||||||
|
ObexHeaderSet pktHeaders(opCode);
|
||||||
|
|
||||||
if (opCode == ObexRequestCode::Connect) {
|
if (opCode == ObexRequestCode::Connect) {
|
||||||
|
ParseHeaders(&aMessage->mData[7], receivedLength - 7, &pktHeaders);
|
||||||
ReplyToConnect();
|
ReplyToConnect();
|
||||||
} else if (opCode == ObexRequestCode::Disconnect) {
|
} else if (opCode == ObexRequestCode::Disconnect) {
|
||||||
|
ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders);
|
||||||
ReplyToDisconnect();
|
ReplyToDisconnect();
|
||||||
} else if (opCode == ObexRequestCode::Put ||
|
} else if (opCode == ObexRequestCode::Put ||
|
||||||
opCode == ObexRequestCode::PutFinal) {
|
opCode == ObexRequestCode::PutFinal) {
|
||||||
|
if (!mReceiving) {
|
||||||
|
MOZ_ASSERT(mPacketLeftLength == 0);
|
||||||
|
ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders);
|
||||||
|
|
||||||
|
pktHeaders.GetName(sFileName);
|
||||||
|
pktHeaders.GetContentType(sContentType);
|
||||||
|
pktHeaders.GetLength(&sFileLength);
|
||||||
|
|
||||||
|
ReceivingFileConfirmation(mConnectedDeviceAddress, sFileName, sFileLength, sContentType);
|
||||||
|
mReceiving = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A PUT request from remote devices may be divided into multiple parts.
|
* A PUT request from remote devices may be divided into multiple parts.
|
||||||
* In other words, one request may need to be received multiple times,
|
* In other words, one request may need to be received multiple times,
|
||||||
* so here we keep a variable mPacketLeftLength to indicate if current
|
* so here we keep a variable mPacketLeftLength to indicate if current
|
||||||
* PUT request is done.
|
* PUT request is done.
|
||||||
*/
|
*/
|
||||||
bool final = (opCode == ObexRequestCode::PutFinal);
|
mPutFinal = (opCode == ObexRequestCode::PutFinal);
|
||||||
|
|
||||||
if (mPacketLeftLength == 0) {
|
if (mPacketLeftLength == 0) {
|
||||||
if (receivedLength < packetLength) {
|
NS_ASSERTION(mPacketLeftLength >= receivedLength,
|
||||||
mPacketLeftLength = packetLength - receivedLength;
|
|
||||||
} else {
|
|
||||||
ReplyToPut(final);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
NS_ASSERTION(mPacketLeftLength < receivedLength,
|
|
||||||
"Invalid packet length");
|
"Invalid packet length");
|
||||||
|
mPacketLeftLength = packetLength - receivedLength;
|
||||||
|
} else {
|
||||||
|
NS_ASSERTION(mPacketLeftLength >= receivedLength,
|
||||||
|
"Invalid packet length");
|
||||||
|
mPacketLeftLength -= receivedLength;
|
||||||
|
}
|
||||||
|
|
||||||
if (mPacketLeftLength <= receivedLength) {
|
if (mPacketLeftLength == 0) {
|
||||||
ReplyToPut(final);
|
ReplyToPut(mPutFinal);
|
||||||
mPacketLeftLength = 0;
|
|
||||||
} else {
|
if (mPutFinal) {
|
||||||
mPacketLeftLength -= receivedLength;
|
mReceiving = false;
|
||||||
|
FileTransferComplete(mConnectedDeviceAddress, true, true, sFileName,
|
||||||
|
sSentFileLength, sContentType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -668,6 +703,39 @@ BluetoothOppManager::UpdateProgress(const nsString& aDeviceAddress,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothOppManager::ReceivingFileConfirmation(const nsString& aAddress,
|
||||||
|
const nsString& aFileName,
|
||||||
|
uint32_t aFileLength,
|
||||||
|
const nsString& aContentType)
|
||||||
|
{
|
||||||
|
nsString type, name;
|
||||||
|
BluetoothValue v;
|
||||||
|
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||||
|
type.AssignLiteral("bluetooth-opp-receiving-file-confirmation");
|
||||||
|
|
||||||
|
name.AssignLiteral("address");
|
||||||
|
v = aAddress;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("fileName");
|
||||||
|
v = aFileName;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("fileLength");
|
||||||
|
v = aFileLength;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
name.AssignLiteral("contentType");
|
||||||
|
v = aContentType;
|
||||||
|
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||||
|
|
||||||
|
if (!BroadcastSystemMessage(type, parameters)) {
|
||||||
|
NS_WARNING("Failed to broadcast [bluetooth-opp-receiving-file-confirmation]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothOppManager::OnConnectSuccess()
|
BluetoothOppManager::OnConnectSuccess()
|
||||||
{
|
{
|
||||||
|
@ -76,6 +76,10 @@ private:
|
|||||||
bool aReceived,
|
bool aReceived,
|
||||||
uint32_t aProcessedLength,
|
uint32_t aProcessedLength,
|
||||||
uint32_t aFileLength);
|
uint32_t aFileLength);
|
||||||
|
void ReceivingFileConfirmation(const nsString& aAddress,
|
||||||
|
const nsString& aFileName,
|
||||||
|
uint32_t aFileLength,
|
||||||
|
const nsString& aContentType);
|
||||||
void ReplyToConnect();
|
void ReplyToConnect();
|
||||||
void ReplyToDisconnect();
|
void ReplyToDisconnect();
|
||||||
void ReplyToPut(bool aFinal);
|
void ReplyToPut(bool aFinal);
|
||||||
@ -92,6 +96,8 @@ private:
|
|||||||
bool mAbortFlag;
|
bool mAbortFlag;
|
||||||
int mPacketLeftLength;
|
int mPacketLeftLength;
|
||||||
nsString mConnectedDeviceAddress;
|
nsString mConnectedDeviceAddress;
|
||||||
|
bool mReceiving;
|
||||||
|
bool mPutFinal;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMBlob> mBlob;
|
nsCOMPtr<nsIDOMBlob> mBlob;
|
||||||
nsCOMPtr<nsIThread> mReadFileThread;
|
nsCOMPtr<nsIThread> mReadFileThread;
|
||||||
|
@ -75,7 +75,7 @@ ParseHeaders(uint8_t* buf, int totalLength, ObexHeaderSet* retHandlerSet)
|
|||||||
|
|
||||||
while (ptr - buf < totalLength) {
|
while (ptr - buf < totalLength) {
|
||||||
ObexHeaderId headerId = (ObexHeaderId)*ptr++;
|
ObexHeaderId headerId = (ObexHeaderId)*ptr++;
|
||||||
int headerLength = 0;
|
int contentLength = 0;
|
||||||
uint8_t highByte, lowByte;
|
uint8_t highByte, lowByte;
|
||||||
|
|
||||||
// Defined in 2.1 OBEX Headers, IrOBEX 1.2
|
// Defined in 2.1 OBEX Headers, IrOBEX 1.2
|
||||||
@ -87,26 +87,31 @@ ParseHeaders(uint8_t* buf, int totalLength, ObexHeaderSet* retHandlerSet)
|
|||||||
// byte sequence, length prefixed with 2 byte unsigned integer.
|
// byte sequence, length prefixed with 2 byte unsigned integer.
|
||||||
highByte = *ptr++;
|
highByte = *ptr++;
|
||||||
lowByte = *ptr++;
|
lowByte = *ptr++;
|
||||||
headerLength = ((int)highByte << 8) | lowByte;
|
contentLength = (((int)highByte << 8) | lowByte) - 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x02:
|
case 0x02:
|
||||||
// 1 byte quantity
|
// 1 byte quantity
|
||||||
headerLength = 1;
|
contentLength = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x03:
|
case 0x03:
|
||||||
// 4 byte quantity
|
// 4 byte quantity
|
||||||
headerLength = 4;
|
contentLength = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Content
|
// FIXME: This case should be happened when we are receiving header 'Body'
|
||||||
uint8_t* headerContent = new uint8_t[headerLength];
|
// (file body). I will handle this in another bug.
|
||||||
memcpy(headerContent, ptr, headerLength);
|
if (contentLength + (ptr - buf) > totalLength) {
|
||||||
retHandlerSet->AddHeader(new ObexHeader(headerId, headerLength, headerContent));
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ptr += headerLength;
|
uint8_t* content = new uint8_t[contentLength];
|
||||||
|
memcpy(content, ptr, contentLength);
|
||||||
|
retHandlerSet->AddHeader(new ObexHeader(headerId, contentLength, content));
|
||||||
|
|
||||||
|
ptr += contentLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +139,56 @@ public:
|
|||||||
{
|
{
|
||||||
mHeaders.AppendElement(aHeader);
|
mHeaders.AppendElement(aHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetName(nsString& aRetName)
|
||||||
|
{
|
||||||
|
int length = mHeaders.Length();
|
||||||
|
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
if (mHeaders[i]->mId == ObexHeaderId::Name) {
|
||||||
|
uint8_t* ptr = mHeaders[i]->mData.get();
|
||||||
|
int nameLength = mHeaders[i]->mDataLength / 2;
|
||||||
|
|
||||||
|
for (int j = 0; j < nameLength; ++j) {
|
||||||
|
PRUnichar c = ((((uint32_t)ptr[j * 2]) << 8) | ptr[j * 2 + 1]);
|
||||||
|
aRetName += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetContentType(nsString& aRetContentType)
|
||||||
|
{
|
||||||
|
int length = mHeaders.Length();
|
||||||
|
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
if (mHeaders[i]->mId == ObexHeaderId::Type) {
|
||||||
|
uint8_t* ptr = mHeaders[i]->mData.get();
|
||||||
|
aRetContentType.AssignASCII((const char*)ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @return file length, 0 means file length is unknown.
|
||||||
|
void GetLength(uint32_t* aRetLength)
|
||||||
|
{
|
||||||
|
int length = mHeaders.Length();
|
||||||
|
*aRetLength = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
if (mHeaders[i]->mId == ObexHeaderId::Length) {
|
||||||
|
uint8_t* ptr = mHeaders[i]->mData.get();
|
||||||
|
*aRetLength = ((uint32_t)ptr[0] << 24) |
|
||||||
|
((uint32_t)ptr[1] << 16) |
|
||||||
|
((uint32_t)ptr[2] << 8) |
|
||||||
|
((uint32_t)ptr[3]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int AppendHeaderName(uint8_t* retBuf, const char* name, int length);
|
int AppendHeaderName(uint8_t* retBuf, const char* name, int length);
|
||||||
|
@ -452,20 +452,56 @@ BrowserElementChild.prototype = {
|
|||||||
|
|
||||||
_recvGetScreenshot: function(data) {
|
_recvGetScreenshot: function(data) {
|
||||||
debug("Received getScreenshot message: (" + data.json.id + ")");
|
debug("Received getScreenshot message: (" + data.json.id + ")");
|
||||||
|
|
||||||
|
// You can think of the screenshotting algorithm as carrying out the
|
||||||
|
// following steps:
|
||||||
|
//
|
||||||
|
// - Let max-width be data.json.args.width, and let max-height be
|
||||||
|
// data.json.args.height.
|
||||||
|
//
|
||||||
|
// - Let scale-width be the factor by which we'd need to downscale the
|
||||||
|
// viewport so it would fit within max-width. (If the viewport's width
|
||||||
|
// is less than max-width, let scale-width be 1.) Compute scale-height
|
||||||
|
// the same way.
|
||||||
|
//
|
||||||
|
// - Scale the viewport by max(scale-width, scale-height). Now either the
|
||||||
|
// viewport's width is no larger than max-width, the viewport's height is
|
||||||
|
// no larger than max-height, or both.
|
||||||
|
//
|
||||||
|
// - Crop the viewport so its width is no larger than max-width and its
|
||||||
|
// height is no larger than max-height.
|
||||||
|
//
|
||||||
|
// - Return a screenshot of the page's viewport scaled and cropped per
|
||||||
|
// above.
|
||||||
|
|
||||||
|
let maxWidth = data.json.args.width;
|
||||||
|
let maxHeight = data.json.args.height;
|
||||||
|
|
||||||
|
let scaleWidth = Math.min(1, maxWidth / content.innerWidth);
|
||||||
|
let scaleHeight = Math.min(1, maxHeight / content.innerHeight);
|
||||||
|
|
||||||
|
let scale = Math.max(scaleWidth, scaleHeight);
|
||||||
|
|
||||||
|
let canvasWidth = Math.min(maxWidth, Math.round(content.innerWidth * scale));
|
||||||
|
let canvasHeight = Math.min(maxHeight, Math.round(content.innerHeight * scale));
|
||||||
|
|
||||||
var canvas = content.document
|
var canvas = content.document
|
||||||
.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||||
var ctx = canvas.getContext("2d");
|
|
||||||
canvas.mozOpaque = true;
|
canvas.mozOpaque = true;
|
||||||
canvas.height = content.innerHeight;
|
canvas.width = canvasWidth;
|
||||||
canvas.width = content.innerWidth;
|
canvas.height = canvasHeight;
|
||||||
ctx.drawWindow(content, 0, 0, content.innerWidth,
|
|
||||||
content.innerHeight, "rgb(255,255,255)");
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.scale(scale, scale);
|
||||||
|
ctx.drawWindow(content, 0, 0, content.innerWidth, content.innerHeight,
|
||||||
|
"rgb(255,255,255)");
|
||||||
|
|
||||||
sendAsyncMsg('got-screenshot', {
|
sendAsyncMsg('got-screenshot', {
|
||||||
id: data.json.id,
|
id: data.json.id,
|
||||||
// Hack around the fact that we can't specify opaque PNG, this requires
|
// Hack around the fact that we can't specify opaque PNG, this requires
|
||||||
// us to unpremultiply the alpha channel which is expensive on ARM
|
// us to unpremultiply the alpha channel which is expensive on ARM
|
||||||
// processors because they lack a hardware integer division instruction.
|
// processors because they lack a hardware integer division instruction.
|
||||||
rv: canvas.toDataURL("image/jpeg")
|
successRv: canvas.toDataURL("image/jpeg")
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -550,7 +586,7 @@ BrowserElementChild.prototype = {
|
|||||||
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
|
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
|
||||||
sendAsyncMsg('got-can-go-back', {
|
sendAsyncMsg('got-can-go-back', {
|
||||||
id: data.json.id,
|
id: data.json.id,
|
||||||
rv: webNav.canGoBack
|
successRv: webNav.canGoBack
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -558,7 +594,7 @@ BrowserElementChild.prototype = {
|
|||||||
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
|
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
|
||||||
sendAsyncMsg('got-can-go-forward', {
|
sendAsyncMsg('got-can-go-forward', {
|
||||||
id: data.json.id,
|
id: data.json.id,
|
||||||
rv: webNav.canGoForward
|
successRv: webNav.canGoForward
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame) {
|
|||||||
defineMethod('goForward', this._goForward);
|
defineMethod('goForward', this._goForward);
|
||||||
defineMethod('reload', this._reload);
|
defineMethod('reload', this._reload);
|
||||||
defineMethod('stop', this._stop);
|
defineMethod('stop', this._stop);
|
||||||
defineDOMRequestMethod('getScreenshot', 'get-screenshot');
|
defineMethod('getScreenshot', this._getScreenshot);
|
||||||
defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
|
defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
|
||||||
defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
|
defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
|
||||||
|
|
||||||
@ -470,15 +470,18 @@ BrowserElementParent.prototype = {
|
|||||||
* Kick off a DOMRequest in the child process.
|
* Kick off a DOMRequest in the child process.
|
||||||
*
|
*
|
||||||
* We'll fire an event called |msgName| on the child process, passing along
|
* We'll fire an event called |msgName| on the child process, passing along
|
||||||
* an object with a single field, id, containing the ID of this request.
|
* an object with two fields:
|
||||||
|
*
|
||||||
|
* - id: the ID of this request.
|
||||||
|
* - arg: arguments to pass to the child along with this request.
|
||||||
*
|
*
|
||||||
* We expect the child to pass the ID back to us upon completion of the
|
* We expect the child to pass the ID back to us upon completion of the
|
||||||
* request; see _gotDOMRequestResult.
|
* request. See _gotDOMRequestResult.
|
||||||
*/
|
*/
|
||||||
_sendDOMRequest: function(msgName) {
|
_sendDOMRequest: function(msgName, args) {
|
||||||
let id = 'req_' + this._domRequestCounter++;
|
let id = 'req_' + this._domRequestCounter++;
|
||||||
let req = Services.DOMRequest.createRequest(this._window);
|
let req = Services.DOMRequest.createRequest(this._window);
|
||||||
if (this._sendAsyncMsg(msgName, {id: id})) {
|
if (this._sendAsyncMsg(msgName, {id: id, args: args})) {
|
||||||
this._pendingDOMRequests[id] = req;
|
this._pendingDOMRequests[id] = req;
|
||||||
} else {
|
} else {
|
||||||
Services.DOMRequest.fireErrorAsync(req, "fail");
|
Services.DOMRequest.fireErrorAsync(req, "fail");
|
||||||
@ -487,17 +490,30 @@ BrowserElementParent.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the child process finishes handling a DOMRequest. We expect
|
* Called when the child process finishes handling a DOMRequest. data.json
|
||||||
* data.json to have two fields:
|
* must have the fields [id, successRv], if the DOMRequest was successful, or
|
||||||
|
* [id, errorMsg], if the request was not successful.
|
||||||
*
|
*
|
||||||
* - id: the ID of the DOM request (see _sendDOMRequest), and
|
* The fields have the following meanings:
|
||||||
* - rv: the request's return value.
|
*
|
||||||
|
* - id: the ID of the DOM request (see _sendDOMRequest)
|
||||||
|
* - successRv: the request's return value, if the request succeeded
|
||||||
|
* - errorMsg: the message to pass to DOMRequest.fireError(), if the request
|
||||||
|
* failed.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
_gotDOMRequestResult: function(data) {
|
_gotDOMRequestResult: function(data) {
|
||||||
let req = this._pendingDOMRequests[data.json.id];
|
let req = this._pendingDOMRequests[data.json.id];
|
||||||
delete this._pendingDOMRequests[data.json.id];
|
delete this._pendingDOMRequests[data.json.id];
|
||||||
Services.DOMRequest.fireSuccess(req, data.json.rv);
|
|
||||||
|
if ('successRv' in data.json) {
|
||||||
|
debug("Successful gotDOMRequestResult.");
|
||||||
|
Services.DOMRequest.fireSuccess(req, data.json.successRv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debug("Got error in gotDOMRequestResult.");
|
||||||
|
Services.DOMRequest.fireErrorAsync(req, data.json.errorMsg);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_setVisible: function(visible) {
|
_setVisible: function(visible) {
|
||||||
@ -548,6 +564,18 @@ BrowserElementParent.prototype = {
|
|||||||
this._sendAsyncMsg('stop');
|
this._sendAsyncMsg('stop');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getScreenshot: function(_width, _height) {
|
||||||
|
let width = parseInt(_width);
|
||||||
|
let height = parseInt(_height);
|
||||||
|
if (isNaN(width) || isNaN(height) || width < 0 || height < 0) {
|
||||||
|
throw Components.Exception("Invalid argument",
|
||||||
|
Cr.NS_ERROR_INVALID_ARG);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._sendDOMRequest('get-screenshot',
|
||||||
|
{width: width, height: height});
|
||||||
|
},
|
||||||
|
|
||||||
_fireKeyEvent: function(data) {
|
_fireKeyEvent: function(data) {
|
||||||
let evt = this._window.document.createEvent("KeyboardEvent");
|
let evt = this._window.document.createEvent("KeyboardEvent");
|
||||||
evt.initKeyEvent(data.json.type, true, true, this._window,
|
evt.initKeyEvent(data.json.type, true, true, this._window,
|
||||||
|
@ -43,6 +43,8 @@ MOCHITEST_FILES = \
|
|||||||
test_browserElement_inproc_Iconchange.html \
|
test_browserElement_inproc_Iconchange.html \
|
||||||
browserElement_GetScreenshot.js \
|
browserElement_GetScreenshot.js \
|
||||||
test_browserElement_inproc_GetScreenshot.html \
|
test_browserElement_inproc_GetScreenshot.html \
|
||||||
|
browserElement_BadScreenshot.js \
|
||||||
|
test_browserElement_inproc_BadScreenshot.html \
|
||||||
browserElement_SetVisible.js \
|
browserElement_SetVisible.js \
|
||||||
test_browserElement_inproc_SetVisible.html \
|
test_browserElement_inproc_SetVisible.html \
|
||||||
browserElement_SetVisibleFrames.js \
|
browserElement_SetVisibleFrames.js \
|
||||||
@ -169,6 +171,7 @@ MOCHITEST_FILES += \
|
|||||||
test_browserElement_oop_TopBarrier.html \
|
test_browserElement_oop_TopBarrier.html \
|
||||||
test_browserElement_oop_Iconchange.html \
|
test_browserElement_oop_Iconchange.html \
|
||||||
test_browserElement_oop_GetScreenshot.html \
|
test_browserElement_oop_GetScreenshot.html \
|
||||||
|
test_browserElement_oop_BadScreenshot.html \
|
||||||
test_browserElement_oop_SetVisible.html \
|
test_browserElement_oop_SetVisible.html \
|
||||||
test_browserElement_oop_SetVisibleFrames.html \
|
test_browserElement_oop_SetVisibleFrames.html \
|
||||||
test_browserElement_oop_SetVisibleFrames2.html \
|
test_browserElement_oop_SetVisibleFrames2.html \
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
/* Any copyright is dedicated to the public domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Bug 800170 - Test that we get errors when we pass bad arguments to
|
||||||
|
// mozbrowser's getScreenshot.
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
var iframe;
|
||||||
|
var numPendingTests = 0;
|
||||||
|
|
||||||
|
// Call iframe.getScreenshot with the given args. If expectSuccess is true, we
|
||||||
|
// expect the screenshot's onsuccess handler to fire. Otherwise, we expect
|
||||||
|
// getScreenshot() to throw an exception.
|
||||||
|
function checkScreenshotResult(expectSuccess, args) {
|
||||||
|
var req;
|
||||||
|
try {
|
||||||
|
req = iframe.getScreenshot.apply(iframe, args);
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
ok(!expectSuccess, "getScreenshot(" + JSON.stringify(args) + ") threw an exception.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
numPendingTests++;
|
||||||
|
req.onsuccess = function() {
|
||||||
|
ok(expectSuccess, "getScreenshot(" + JSON.stringify(args) + ") succeeded.");
|
||||||
|
numPendingTests--;
|
||||||
|
if (numPendingTests == 0) {
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// We never expect to see onerror.
|
||||||
|
req.onerror = function() {
|
||||||
|
ok(false, "getScreenshot(" + JSON.stringify(args) + ") ran onerror.");
|
||||||
|
numPendingTests--;
|
||||||
|
if (numPendingTests == 0) {
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
dump("XXX runTest\n");
|
||||||
|
browserElementTestHelpers.setEnabledPref(true);
|
||||||
|
browserElementTestHelpers.addPermission();
|
||||||
|
|
||||||
|
iframe = document.createElement('iframe');
|
||||||
|
iframe.mozbrowser = true;
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
iframe.src = 'data:text/html,<html>' +
|
||||||
|
'<body style="background:green">hello</body></html>';
|
||||||
|
|
||||||
|
iframe.addEventListener('mozbrowserfirstpaint', function() {
|
||||||
|
// This one should succeed.
|
||||||
|
checkScreenshotResult(true, [100, 100]);
|
||||||
|
|
||||||
|
// These should fail.
|
||||||
|
checkScreenshotResult(false, []);
|
||||||
|
checkScreenshotResult(false, [100]);
|
||||||
|
checkScreenshotResult(false, ['a', 100]);
|
||||||
|
checkScreenshotResult(false, [100, 'a']);
|
||||||
|
checkScreenshotResult(false, [-1, 100]);
|
||||||
|
checkScreenshotResult(false, [100, -1]);
|
||||||
|
|
||||||
|
if (numPendingTests == 0) {
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
runTest();
|
@ -27,7 +27,7 @@ function runTest() {
|
|||||||
SimpleTest.executeSoon(nextTest);
|
SimpleTest.executeSoon(nextTest);
|
||||||
}
|
}
|
||||||
|
|
||||||
var domRequest = iframe1.getScreenshot();
|
var domRequest = iframe1.getScreenshot(1000, 1000);
|
||||||
domRequest.onsuccess = function(e) {
|
domRequest.onsuccess = function(e) {
|
||||||
testEnd();
|
testEnd();
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ function runTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We continually take screenshots until we get one that we are
|
// We continually take screenshots until we get one that we are
|
||||||
// happy with
|
// happy with.
|
||||||
function waitForScreenshot(filter) {
|
function waitForScreenshot(filter) {
|
||||||
|
|
||||||
function screenshotLoaded(e) {
|
function screenshotLoaded(e) {
|
||||||
@ -50,13 +50,13 @@ function runTest() {
|
|||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
} else {
|
} else {
|
||||||
content.document.defaultView.setTimeout(function() {
|
content.document.defaultView.setTimeout(function() {
|
||||||
iframe1.getScreenshot().onsuccess = screenshotLoaded;
|
iframe1.getScreenshot(1000, 1000).onsuccess = screenshotLoaded;
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var attempts = 10;
|
var attempts = 10;
|
||||||
iframe1.getScreenshot().onsuccess = screenshotLoaded;
|
iframe1.getScreenshot(1000, 1000).onsuccess = screenshotLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
function iframeLoadedHandler() {
|
function iframeLoadedHandler() {
|
||||||
@ -72,5 +72,3 @@ function runTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addEventListener('load', function() { SimpleTest.executeSoon(runTest); });
|
addEventListener('load', function() { SimpleTest.executeSoon(runTest); });
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ function runTest() {
|
|||||||
else if (e.detail.message == 'finish') {
|
else if (e.detail.message == 'finish') {
|
||||||
// We assume here that iframe is completely blank, and spin until popup's
|
// We assume here that iframe is completely blank, and spin until popup's
|
||||||
// screenshot is not the same as iframe.
|
// screenshot is not the same as iframe.
|
||||||
iframe.getScreenshot().onsuccess = function(e) {
|
iframe.getScreenshot(1000, 1000).onsuccess = function(e) {
|
||||||
test2(popup, e.target.result, popup);
|
test2(popup, e.target.result, popup);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ var prevScreenshot;
|
|||||||
function test2(popup, blankScreenshot) {
|
function test2(popup, blankScreenshot) {
|
||||||
// Take screenshots of popup until it doesn't equal blankScreenshot (or we
|
// Take screenshots of popup until it doesn't equal blankScreenshot (or we
|
||||||
// time out).
|
// time out).
|
||||||
popup.getScreenshot().onsuccess = function(e) {
|
popup.getScreenshot(1000, 1000).onsuccess = function(e) {
|
||||||
var screenshot = e.target.result;
|
var screenshot = e.target.result;
|
||||||
if (screenshot != blankScreenshot) {
|
if (screenshot != blankScreenshot) {
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
@ -25,7 +25,7 @@ function runTest() {
|
|||||||
// taking the screenshot).
|
// taking the screenshot).
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
iframe.getScreenshot().onsuccess = function(sshot) {
|
iframe.getScreenshot(1000, 1000).onsuccess = function(sshot) {
|
||||||
if (initialScreenshot == null)
|
if (initialScreenshot == null)
|
||||||
initialScreenshot = sshot.target.result;
|
initialScreenshot = sshot.target.result;
|
||||||
e.detail.unblock();
|
e.detail.unblock();
|
||||||
@ -37,7 +37,7 @@ function runTest() {
|
|||||||
case 'finish':
|
case 'finish':
|
||||||
// The page has now attempted to load the X-Frame-Options page; take
|
// The page has now attempted to load the X-Frame-Options page; take
|
||||||
// another screenshot.
|
// another screenshot.
|
||||||
iframe.getScreenshot().onsuccess = function(sshot) {
|
iframe.getScreenshot(1000, 1000).onsuccess = function(sshot) {
|
||||||
is(sshot.target.result, initialScreenshot, "Screenshots should be identical");
|
is(sshot.target.result, initialScreenshot, "Screenshots should be identical");
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@ function runTest() {
|
|||||||
// taking the screenshot).
|
// taking the screenshot).
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
iframe.getScreenshot().onsuccess = function(sshot) {
|
iframe.getScreenshot(1000, 1000).onsuccess = function(sshot) {
|
||||||
initialScreenshot = sshot.target.result;
|
initialScreenshot = sshot.target.result;
|
||||||
e.detail.unblock();
|
e.detail.unblock();
|
||||||
};
|
};
|
||||||
@ -36,7 +36,7 @@ function runTest() {
|
|||||||
case 'step 2':
|
case 'step 2':
|
||||||
// The page has now attempted to load the X-Frame-Options page; take
|
// The page has now attempted to load the X-Frame-Options page; take
|
||||||
// another screenshot.
|
// another screenshot.
|
||||||
iframe.getScreenshot().onsuccess = function(sshot) {
|
iframe.getScreenshot(1000, 1000).onsuccess = function(sshot) {
|
||||||
is(sshot.target.result, initialScreenshot, "Screenshots should be identical");
|
is(sshot.target.result, initialScreenshot, "Screenshots should be identical");
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test for Bug 800170</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="application/javascript;version=1.7" src="browserElement_BadScreenshot.js">
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test for Bug 800170</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="application/javascript;version=1.7" src="browserElement_BadScreenshot.js">
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -21,10 +21,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={674720}
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var comp = SpecialPowers.wrap(SpecialPowers.Components);
|
// this shouldn't be necessary when bug 792594 is fixed
|
||||||
comp.utils.import("resource://gre/modules/ContactService.jsm");
|
if (!SpecialPowers.getBoolPref("dom.mozContacts.enabled")) {
|
||||||
comp.utils.import("resource://gre/modules/PermissionPromptHelper.jsm");
|
var comp = SpecialPowers.wrap(SpecialPowers.Components);
|
||||||
SpecialPowers.setBoolPref("dom.mozContacts.enabled", true);
|
comp.utils.import("resource://gre/modules/ContactService.jsm");
|
||||||
|
comp.utils.import("resource://gre/modules/PermissionPromptHelper.jsm");
|
||||||
|
SpecialPowers.setBoolPref("dom.mozContacts.enabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
SpecialPowers.addPermission("contacts", true, document);
|
SpecialPowers.addPermission("contacts", true, document);
|
||||||
|
|
||||||
// For Sorting
|
// For Sorting
|
||||||
|
@ -21,10 +21,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={674720}
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var comp = SpecialPowers.wrap(SpecialPowers.Components);
|
// this shouldn't be necessary when bug 792594 is fixed
|
||||||
comp.utils.import("resource://gre/modules/ContactService.jsm");
|
if (!SpecialPowers.getBoolPref("dom.mozContacts.enabled")) {
|
||||||
comp.utils.import("resource://gre/modules/PermissionPromptHelper.jsm");
|
var comp = SpecialPowers.wrap(SpecialPowers.Components);
|
||||||
SpecialPowers.setBoolPref("dom.mozContacts.enabled", true);
|
comp.utils.import("resource://gre/modules/ContactService.jsm");
|
||||||
|
comp.utils.import("resource://gre/modules/PermissionPromptHelper.jsm");
|
||||||
|
SpecialPowers.setBoolPref("dom.mozContacts.enabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
SpecialPowers.addPermission("contacts", true, document);
|
SpecialPowers.addPermission("contacts", true, document);
|
||||||
|
|
||||||
var utils = SpecialPowers.getDOMWindowUtils(window);
|
var utils = SpecialPowers.getDOMWindowUtils(window);
|
||||||
|
@ -345,9 +345,6 @@ test(
|
|||||||
continue;
|
continue;
|
||||||
if (encoding === "iso-2022-kr" && (i === 0x0E || i === 0x0F || i === 0x1B))
|
if (encoding === "iso-2022-kr" && (i === 0x0E || i === 0x0F || i === 0x1B))
|
||||||
continue;
|
continue;
|
||||||
// TODO: Gecko decoder bugs
|
|
||||||
if ((encoding === "big5" || encoding === "euc-kr") && i === 0x7F)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
string += String.fromCharCode(i);
|
string += String.fromCharCode(i);
|
||||||
bytes.push(i);
|
bytes.push(i);
|
||||||
|
@ -25,7 +25,7 @@ windows-1250.title = Central European (Windows-1250)
|
|||||||
windows-1252.title = Western (Windows-1252)
|
windows-1252.title = Western (Windows-1252)
|
||||||
windows-1254.title = Turkish (Windows-1254)
|
windows-1254.title = Turkish (Windows-1254)
|
||||||
windows-1257.title = Baltic (Windows-1257)
|
windows-1257.title = Baltic (Windows-1257)
|
||||||
x-mac-roman.title = Western (MacRoman)
|
macintosh.title = Western (MacRoman)
|
||||||
x-mac-ce.title = Central European (MacCE)
|
x-mac-ce.title = Central European (MacCE)
|
||||||
x-mac-turkish.title = Turkish (MacTurkish)
|
x-mac-turkish.title = Turkish (MacTurkish)
|
||||||
x-mac-croatian.title = Croatian (MacCroatian)
|
x-mac-croatian.title = Croatian (MacCroatian)
|
||||||
|
@ -443,6 +443,7 @@ public:
|
|||||||
nsresult
|
nsresult
|
||||||
SelectDevice()
|
SelectDevice()
|
||||||
{
|
{
|
||||||
|
bool found = false;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
if (mPicture || mVideo) {
|
if (mPicture || mVideo) {
|
||||||
nsTArray<nsRefPtr<MediaEngineVideoSource> > videoSources;
|
nsTArray<nsRefPtr<MediaEngineVideoSource> > videoSources;
|
||||||
@ -455,7 +456,22 @@ public:
|
|||||||
));
|
));
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
mVideoDevice = new MediaDevice(videoSources[0]);
|
|
||||||
|
// Pick the first available device.
|
||||||
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
|
nsRefPtr<MediaEngineVideoSource> vSource = videoSources[i];
|
||||||
|
if (vSource->IsAvailable()) {
|
||||||
|
found = true;
|
||||||
|
mVideoDevice = new MediaDevice(videoSources[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
NS_DispatchToMainThread(new ErrorCallbackRunnable(
|
||||||
|
mSuccess, mError, NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID
|
||||||
|
));
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
LOG(("Selected video device"));
|
LOG(("Selected video device"));
|
||||||
}
|
}
|
||||||
if (mAudio) {
|
if (mAudio) {
|
||||||
@ -469,7 +485,21 @@ public:
|
|||||||
));
|
));
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
mAudioDevice = new MediaDevice(audioSources[0]);
|
|
||||||
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
|
nsRefPtr<MediaEngineAudioSource> aSource = audioSources[i];
|
||||||
|
if (aSource->IsAvailable()) {
|
||||||
|
found = true;
|
||||||
|
mAudioDevice = new MediaDevice(audioSources[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
NS_DispatchToMainThread(new ErrorCallbackRunnable(
|
||||||
|
mSuccess, mError, NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID
|
||||||
|
));
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
LOG(("Selected audio device"));
|
LOG(("Selected audio device"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,11 +626,23 @@ public:
|
|||||||
nsTArray<nsCOMPtr<nsIMediaDevice> > *devices =
|
nsTArray<nsCOMPtr<nsIMediaDevice> > *devices =
|
||||||
new nsTArray<nsCOMPtr<nsIMediaDevice> >;
|
new nsTArray<nsCOMPtr<nsIMediaDevice> >;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We only display available devices in the UI for now. We can easily
|
||||||
|
* change this later, when we implement a more sophisticated UI that
|
||||||
|
* lets the user revoke a device currently held by another tab (or
|
||||||
|
* we decide to provide a stream from a device already allocated).
|
||||||
|
*/
|
||||||
for (i = 0; i < videoCount; i++) {
|
for (i = 0; i < videoCount; i++) {
|
||||||
devices->AppendElement(new MediaDevice(videoSources[i]));
|
nsRefPtr<MediaEngineVideoSource> vSource = videoSources[i];
|
||||||
|
if (vSource->IsAvailable()) {
|
||||||
|
devices->AppendElement(new MediaDevice(vSource));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < audioCount; i++) {
|
for (i = 0; i < audioCount; i++) {
|
||||||
devices->AppendElement(new MediaDevice(audioSources[i]));
|
nsRefPtr<MediaEngineAudioSource> aSource = audioSources[i];
|
||||||
|
if (aSource->IsAvailable()) {
|
||||||
|
devices->AppendElement(new MediaDevice(aSource));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(
|
NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(
|
||||||
|
@ -110,6 +110,8 @@ public:
|
|||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
SourceMediaStream* stream = mStream->GetStream()->AsSourceStream();
|
SourceMediaStream* stream = mStream->GetStream()->AsSourceStream();
|
||||||
|
stream->SetPullEnabled(true);
|
||||||
|
|
||||||
if (mAudioSource) {
|
if (mAudioSource) {
|
||||||
rv = mAudioSource->Start(stream, kAudioTrack);
|
rv = mAudioSource->Start(stream, kAudioTrack);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
@ -122,6 +124,7 @@ public:
|
|||||||
MM_LOG(("Starting video failed, rv=%d",rv));
|
MM_LOG(("Starting video failed, rv=%d",rv));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MM_LOG(("started all sources"));
|
MM_LOG(("started all sources"));
|
||||||
nsCOMPtr<GetUserMediaNotificationEvent> event =
|
nsCOMPtr<GetUserMediaNotificationEvent> event =
|
||||||
new GetUserMediaNotificationEvent(GetUserMediaNotificationEvent::STARTING);
|
new GetUserMediaNotificationEvent(GetUserMediaNotificationEvent::STARTING);
|
||||||
@ -135,6 +138,20 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Proxy NotifyPull() to sources
|
||||||
|
void
|
||||||
|
NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime)
|
||||||
|
{
|
||||||
|
// Currently audio sources ignore NotifyPull, but they could
|
||||||
|
// watch it especially for fake audio.
|
||||||
|
if (mAudioSource) {
|
||||||
|
mAudioSource->NotifyPull(aGraph, aDesiredTime);
|
||||||
|
}
|
||||||
|
if (mVideoSource) {
|
||||||
|
mVideoSource->NotifyPull(aGraph, aDesiredTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<MediaEngineSource> mAudioSource;
|
nsRefPtr<MediaEngineSource> mAudioSource;
|
||||||
nsRefPtr<MediaEngineSource> mVideoSource;
|
nsRefPtr<MediaEngineSource> mVideoSource;
|
||||||
|
@ -174,8 +174,9 @@ SystemMessageManager.prototype = {
|
|||||||
" (" + this._manifest + ")");
|
" (" + this._manifest + ")");
|
||||||
|
|
||||||
let msg = aMessage.json;
|
let msg = aMessage.json;
|
||||||
if (msg.manifest != this._manifest)
|
if (msg.manifest != this._manifest || msg.uri != this._uri) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Send an acknowledgement to parent to clean up the pending message,
|
// Send an acknowledgement to parent to clean up the pending message,
|
||||||
// so a re-launched app won't handle it again, which is redundant.
|
// so a re-launched app won't handle it again, which is redundant.
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
#include "nsIDOMEvent.idl"
|
#include "nsIDOMEvent.idl"
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(1b8ea6e4-8142-4aba-b174-4d580b5bc294)]
|
[scriptable, builtinclass, uuid(c0de7fba-725f-4180-b1f1-83163014d1e2)]
|
||||||
interface nsIDOMUSSDReceivedEvent : nsIDOMEvent
|
interface nsIDOMUSSDReceivedEvent : nsIDOMEvent
|
||||||
{
|
{
|
||||||
readonly attribute DOMString message;
|
readonly attribute DOMString message;
|
||||||
|
[infallible] readonly attribute boolean sessionEnded;
|
||||||
};
|
};
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include "nsJSON.h"
|
#include "nsJSON.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/USSDReceivedEventBinding.h"
|
||||||
|
|
||||||
#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
|
#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
|
||||||
|
|
||||||
#define VOICECHANGE_EVENTNAME NS_LITERAL_STRING("voicechange")
|
#define VOICECHANGE_EVENTNAME NS_LITERAL_STRING("voicechange")
|
||||||
@ -157,13 +159,15 @@ MobileConnection::Observe(nsISupports* aSubject,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(aTopic, kUssdReceivedTopic)) {
|
if (!strcmp(aTopic, kUssdReceivedTopic)) {
|
||||||
nsString ussd;
|
mozilla::dom::USSDReceivedEventDict dict;
|
||||||
ussd.Assign(aData);
|
bool ok = dict.Init(nsDependentString(aData));
|
||||||
nsRefPtr<USSDReceivedEvent> event = USSDReceivedEvent::Create(ussd);
|
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsRefPtr<USSDReceivedEvent> event =
|
||||||
|
USSDReceivedEvent::Create(dict.message, dict.sessionEnded);
|
||||||
NS_ASSERTION(event, "This should never fail!");
|
NS_ASSERTION(event, "This should never fail!");
|
||||||
|
|
||||||
nsresult rv =
|
nsresult rv = event->Dispatch(ToIDOMEventTarget(), USSDRECEIVED_EVENTNAME);
|
||||||
event->Dispatch(ToIDOMEventTarget(), USSDRECEIVED_EVENTNAME);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,14 @@ namespace dom {
|
|||||||
namespace network {
|
namespace network {
|
||||||
|
|
||||||
already_AddRefed<USSDReceivedEvent>
|
already_AddRefed<USSDReceivedEvent>
|
||||||
USSDReceivedEvent::Create(nsAString& aMessage)
|
USSDReceivedEvent::Create(nsAString& aMessage, bool aSessionEnded)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!aMessage.IsEmpty(), "Empty message!");
|
NS_ASSERTION(!aMessage.IsEmpty(), "Empty message!");
|
||||||
|
|
||||||
nsRefPtr<USSDReceivedEvent> event = new USSDReceivedEvent();
|
nsRefPtr<USSDReceivedEvent> event = new USSDReceivedEvent();
|
||||||
|
|
||||||
event->mMessage = aMessage;
|
event->mMessage = aMessage;
|
||||||
|
event->mSessionEnded = aSessionEnded;
|
||||||
|
|
||||||
return event.forget();
|
return event.forget();
|
||||||
}
|
}
|
||||||
@ -40,6 +41,13 @@ USSDReceivedEvent::GetMessage(nsAString& aMessage)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [infallible] */ NS_IMETHODIMP
|
||||||
|
USSDReceivedEvent::GetSessionEnded(bool* aSessionEnded)
|
||||||
|
{
|
||||||
|
*aSessionEnded = mSessionEnded;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ class USSDReceivedEvent : public nsDOMEvent,
|
|||||||
public nsIDOMUSSDReceivedEvent
|
public nsIDOMUSSDReceivedEvent
|
||||||
{
|
{
|
||||||
nsString mMessage;
|
nsString mMessage;
|
||||||
|
bool mSessionEnded;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
@ -23,7 +24,7 @@ public:
|
|||||||
NS_DECL_NSIDOMUSSDRECEIVEDEVENT
|
NS_DECL_NSIDOMUSSDRECEIVEDEVENT
|
||||||
|
|
||||||
static already_AddRefed<USSDReceivedEvent>
|
static already_AddRefed<USSDReceivedEvent>
|
||||||
Create(nsAString& aMessage);
|
Create(nsAString& aMessage, bool aSessionEnded);
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
Dispatch(nsIDOMEventTarget* aTarget, const nsAString& aEventType)
|
Dispatch(nsIDOMEventTarget* aTarget, const nsAString& aEventType)
|
||||||
|
@ -277,6 +277,13 @@ PluginPRLibrary::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing)
|
|||||||
*aDrawing = false;
|
*aDrawing = false;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
nsresult
|
||||||
|
PluginPRLibrary::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor)
|
||||||
|
{
|
||||||
|
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
|
||||||
|
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -114,6 +114,7 @@ public:
|
|||||||
virtual bool IsOOP() MOZ_OVERRIDE { return false; }
|
virtual bool IsOOP() MOZ_OVERRIDE { return false; }
|
||||||
#if defined(XP_MACOSX)
|
#if defined(XP_MACOSX)
|
||||||
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
|
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
|
||||||
|
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor);
|
||||||
#endif
|
#endif
|
||||||
virtual nsresult SetBackgroundUnknown(NPP instance) MOZ_OVERRIDE;
|
virtual nsresult SetBackgroundUnknown(NPP instance) MOZ_OVERRIDE;
|
||||||
virtual nsresult BeginUpdateBackground(NPP instance,
|
virtual nsresult BeginUpdateBackground(NPP instance,
|
||||||
|
@ -1081,6 +1081,26 @@ nsresult nsNPAPIPluginInstance::IsRemoteDrawingCoreAnimation(bool* aDrawing)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult nsNPAPIPluginInstance::ContentsScaleFactorChanged(double aContentsScaleFactor)
|
||||||
|
{
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
if (!mPlugin)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PluginLibrary* library = mPlugin->GetLibrary();
|
||||||
|
if (!library)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// We only need to call this if the plugin is running OOP.
|
||||||
|
if (!library->IsOOP())
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
return library->ContentsScaleFactorChanged(&mNPP, aContentsScaleFactor);
|
||||||
|
#else
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsNPAPIPluginInstance::GetJSObject(JSContext *cx, JSObject** outObject)
|
nsNPAPIPluginInstance::GetJSObject(JSContext *cx, JSObject** outObject)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,7 @@ public:
|
|||||||
nsresult GetValueFromPlugin(NPPVariable variable, void* value);
|
nsresult GetValueFromPlugin(NPPVariable variable, void* value);
|
||||||
nsresult GetDrawingModel(int32_t* aModel);
|
nsresult GetDrawingModel(int32_t* aModel);
|
||||||
nsresult IsRemoteDrawingCoreAnimation(bool* aDrawing);
|
nsresult IsRemoteDrawingCoreAnimation(bool* aDrawing);
|
||||||
|
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
|
||||||
nsresult GetJSObject(JSContext *cx, JSObject** outObject);
|
nsresult GetJSObject(JSContext *cx, JSObject** outObject);
|
||||||
bool ShouldCache();
|
bool ShouldCache();
|
||||||
nsresult IsWindowless(bool* isWindowless);
|
nsresult IsWindowless(bool* isWindowless);
|
||||||
|
@ -984,7 +984,7 @@ static const moz2javaCharset charsets[] =
|
|||||||
{"x-mac-greek", "MacGreek"},
|
{"x-mac-greek", "MacGreek"},
|
||||||
{"x-mac-hebrew", "MacHebrew"},
|
{"x-mac-hebrew", "MacHebrew"},
|
||||||
{"x-mac-icelandic", "MacIceland"},
|
{"x-mac-icelandic", "MacIceland"},
|
||||||
{"x-mac-roman", "MacRoman"},
|
{"macintosh", "MacRoman"},
|
||||||
{"x-mac-romanian", "MacRomania"},
|
{"x-mac-romanian", "MacRomania"},
|
||||||
{"x-mac-ukrainian", "MacUkraine"},
|
{"x-mac-ukrainian", "MacUkraine"},
|
||||||
{"Shift_JIS", "SJIS"},
|
{"Shift_JIS", "SJIS"},
|
||||||
@ -1370,6 +1370,14 @@ bool nsPluginInstanceOwner::IsRemoteDrawingCoreAnimation()
|
|||||||
return coreAnimation;
|
return coreAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult nsPluginInstanceOwner::ContentsScaleFactorChanged(double aContentsScaleFactor)
|
||||||
|
{
|
||||||
|
if (!mInstance) {
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
return mInstance->ContentsScaleFactorChanged(aContentsScaleFactor);
|
||||||
|
}
|
||||||
|
|
||||||
NPEventModel nsPluginInstanceOwner::GetEventModel()
|
NPEventModel nsPluginInstanceOwner::GetEventModel()
|
||||||
{
|
{
|
||||||
return mEventModel;
|
return mEventModel;
|
||||||
|
@ -116,6 +116,7 @@ public:
|
|||||||
|
|
||||||
NPDrawingModel GetDrawingModel();
|
NPDrawingModel GetDrawingModel();
|
||||||
bool IsRemoteDrawingCoreAnimation();
|
bool IsRemoteDrawingCoreAnimation();
|
||||||
|
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
|
||||||
NPEventModel GetEventModel();
|
NPEventModel GetEventModel();
|
||||||
static void CARefresh(nsITimer *aTimer, void *aClosure);
|
static void CARefresh(nsITimer *aTimer, void *aClosure);
|
||||||
void AddToCARefreshTimer();
|
void AddToCARefreshTimer();
|
||||||
|
@ -118,6 +118,9 @@ child:
|
|||||||
returns (int16_t handled);
|
returns (int16_t handled);
|
||||||
// this is only used on windows to forward WM_WINDOWPOSCHANGE
|
// this is only used on windows to forward WM_WINDOWPOSCHANGE
|
||||||
async WindowPosChanged(NPRemoteEvent event);
|
async WindowPosChanged(NPRemoteEvent event);
|
||||||
|
// used on OS X to tell the child the contents scale factor
|
||||||
|
// of its parent has changed
|
||||||
|
async ContentsScaleFactorChanged(double aContentsScaleFactor);
|
||||||
|
|
||||||
// ********************** Async plugins rendering
|
// ********************** Async plugins rendering
|
||||||
// see https://wiki.mozilla.org/Gecko:AsyncPluginPainting
|
// see https://wiki.mozilla.org/Gecko:AsyncPluginPainting
|
||||||
|
@ -1013,6 +1013,24 @@ PluginInstanceChild::RecvWindowPosChanged(const NPRemoteEvent& event)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PluginInstanceChild::RecvContentsScaleFactorChanged(const double& aContentsScaleFactor)
|
||||||
|
{
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
mContentsScaleFactor = aContentsScaleFactor;
|
||||||
|
if (mShContext) {
|
||||||
|
// Release the shared context so that it is reallocated
|
||||||
|
// with the new size.
|
||||||
|
::CGContextRelease(mShContext);
|
||||||
|
mShContext = nullptr;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
NS_RUNTIMEABORT("ContentsScaleFactorChanged is an OSX-only message");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||||
// Create a new window from NPWindow
|
// Create a new window from NPWindow
|
||||||
bool PluginInstanceChild::CreateWindow(const NPRemoteWindow& aWindow)
|
bool PluginInstanceChild::CreateWindow(const NPRemoteWindow& aWindow)
|
||||||
@ -3957,7 +3975,9 @@ PluginInstanceChild::SwapSurfaces()
|
|||||||
(mDoubleBufferCARenderer.GetFrontSurfaceWidth() !=
|
(mDoubleBufferCARenderer.GetFrontSurfaceWidth() !=
|
||||||
mDoubleBufferCARenderer.GetBackSurfaceWidth() ||
|
mDoubleBufferCARenderer.GetBackSurfaceWidth() ||
|
||||||
mDoubleBufferCARenderer.GetFrontSurfaceHeight() !=
|
mDoubleBufferCARenderer.GetFrontSurfaceHeight() !=
|
||||||
mDoubleBufferCARenderer.GetBackSurfaceHeight())) {
|
mDoubleBufferCARenderer.GetBackSurfaceHeight() ||
|
||||||
|
mDoubleBufferCARenderer.GetFrontSurfaceContentsScaleFactor() !=
|
||||||
|
mDoubleBufferCARenderer.GetBackSurfaceContentsScaleFactor())) {
|
||||||
|
|
||||||
mDoubleBufferCARenderer.ClearFrontSurface();
|
mDoubleBufferCARenderer.ClearFrontSurface();
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,9 @@ protected:
|
|||||||
virtual bool
|
virtual bool
|
||||||
RecvWindowPosChanged(const NPRemoteEvent& event) MOZ_OVERRIDE;
|
RecvWindowPosChanged(const NPRemoteEvent& event) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvContentsScaleFactorChanged(const double& aContentsScaleFactor) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
AnswerNPP_Destroy(NPError* result);
|
AnswerNPP_Destroy(NPError* result);
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginEventModel(
|
|||||||
{
|
{
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
*result = mNPNIface->setvalue(mNPP, NPPVpluginEventModel,
|
*result = mNPNIface->setvalue(mNPP, NPPVpluginEventModel,
|
||||||
(void*)eventModel);
|
(void*)(intptr_t)eventModel);
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
*result = NPERR_GENERIC_ERROR;
|
*result = NPERR_GENERIC_ERROR;
|
||||||
@ -799,7 +799,14 @@ PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing)
|
|||||||
NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
|
NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
nsresult
|
||||||
|
PluginInstanceParent::ContentsScaleFactorChanged(double aContentsScaleFactor)
|
||||||
|
{
|
||||||
|
bool rv = SendContentsScaleFactorChanged(aContentsScaleFactor);
|
||||||
|
return rv ? NS_OK : NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
#endif // #ifdef XP_MACOSX
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
PluginInstanceParent::SetBackgroundUnknown()
|
PluginInstanceParent::SetBackgroundUnknown()
|
||||||
|
@ -271,6 +271,7 @@ public:
|
|||||||
nsresult GetImageSize(nsIntSize* aSize);
|
nsresult GetImageSize(nsIntSize* aSize);
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
nsresult IsRemoteDrawingCoreAnimation(bool *aDrawing);
|
nsresult IsRemoteDrawingCoreAnimation(bool *aDrawing);
|
||||||
|
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
|
||||||
#endif
|
#endif
|
||||||
nsresult SetBackgroundUnknown();
|
nsresult SetBackgroundUnknown();
|
||||||
nsresult BeginUpdateBackground(const nsIntRect& aRect,
|
nsresult BeginUpdateBackground(const nsIntRect& aRect,
|
||||||
|
@ -73,6 +73,7 @@ public:
|
|||||||
virtual bool IsOOP() = 0;
|
virtual bool IsOOP() = 0;
|
||||||
#if defined(XP_MACOSX)
|
#if defined(XP_MACOSX)
|
||||||
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) = 0;
|
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) = 0;
|
||||||
|
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1185,7 +1185,17 @@ PluginModuleParent::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing)
|
|||||||
|
|
||||||
return i->IsRemoteDrawingCoreAnimation(aDrawing);
|
return i->IsRemoteDrawingCoreAnimation(aDrawing);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
nsresult
|
||||||
|
PluginModuleParent::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor)
|
||||||
|
{
|
||||||
|
PluginInstanceParent* i = InstCast(instance);
|
||||||
|
if (!i)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
return i->ContentsScaleFactorChanged(aContentsScaleFactor);
|
||||||
|
}
|
||||||
|
#endif // #if defined(XP_MACOSX)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PluginModuleParent::AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable,
|
PluginModuleParent::AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable,
|
||||||
|
@ -271,6 +271,7 @@ private:
|
|||||||
|
|
||||||
#if defined(XP_MACOSX)
|
#if defined(XP_MACOSX)
|
||||||
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
|
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
|
||||||
|
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
|
#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
|
||||||
virtual nsresult HandleGUIEvent(NPP instance, const nsGUIEvent& anEvent,
|
virtual nsresult HandleGUIEvent(NPP instance, const nsGUIEvent& anEvent,
|
||||||
|
@ -50,12 +50,14 @@ public:
|
|||||||
// Returns height in "display pixels". Multiply by
|
// Returns height in "display pixels". Multiply by
|
||||||
// mContentsScaleFactor to get device pixels.
|
// mContentsScaleFactor to get device pixels.
|
||||||
size_t GetFrontSurfaceHeight();
|
size_t GetFrontSurfaceHeight();
|
||||||
|
double GetFrontSurfaceContentsScaleFactor();
|
||||||
// Returns width in "display pixels". Multiply by
|
// Returns width in "display pixels". Multiply by
|
||||||
// mContentsScaleFactor to get device pixels.
|
// mContentsScaleFactor to get device pixels.
|
||||||
size_t GetBackSurfaceWidth();
|
size_t GetBackSurfaceWidth();
|
||||||
// Returns height in "display pixels". Multiply by
|
// Returns height in "display pixels". Multiply by
|
||||||
// mContentsScaleFactor to get device pixels.
|
// mContentsScaleFactor to get device pixels.
|
||||||
size_t GetBackSurfaceHeight();
|
size_t GetBackSurfaceHeight();
|
||||||
|
double GetBackSurfaceContentsScaleFactor();
|
||||||
IOSurfaceID GetFrontSurfaceID();
|
IOSurfaceID GetFrontSurfaceID();
|
||||||
|
|
||||||
bool HasBackSurface();
|
bool HasBackSurface();
|
||||||
|
@ -269,6 +269,14 @@ size_t nsDoubleBufferCARenderer::GetFrontSurfaceHeight() {
|
|||||||
return mFrontSurface->GetHeight();
|
return mFrontSurface->GetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double nsDoubleBufferCARenderer::GetFrontSurfaceContentsScaleFactor() {
|
||||||
|
if (!HasFrontSurface()) {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mFrontSurface->GetContentsScaleFactor();
|
||||||
|
}
|
||||||
|
|
||||||
size_t nsDoubleBufferCARenderer::GetBackSurfaceWidth() {
|
size_t nsDoubleBufferCARenderer::GetBackSurfaceWidth() {
|
||||||
if (!HasBackSurface()) {
|
if (!HasBackSurface()) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -285,6 +293,14 @@ size_t nsDoubleBufferCARenderer::GetBackSurfaceHeight() {
|
|||||||
return mBackSurface->GetHeight();
|
return mBackSurface->GetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double nsDoubleBufferCARenderer::GetBackSurfaceContentsScaleFactor() {
|
||||||
|
if (!HasBackSurface()) {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mBackSurface->GetContentsScaleFactor();
|
||||||
|
}
|
||||||
|
|
||||||
IOSurfaceID nsDoubleBufferCARenderer::GetFrontSurfaceID() {
|
IOSurfaceID nsDoubleBufferCARenderer::GetFrontSurfaceID() {
|
||||||
if (!HasFrontSurface()) {
|
if (!HasFrontSurface()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -710,14 +710,15 @@ RILContentHelper.prototype = {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "RIL:USSDReceived":
|
case "RIL:USSDReceived":
|
||||||
Services.obs.notifyObservers(null, kUssdReceivedTopic,
|
let res = JSON.stringify({message: msg.json.message,
|
||||||
msg.json.message);
|
sessionEnded: msg.json.sessionEnded});
|
||||||
|
Services.obs.notifyObservers(null, kUssdReceivedTopic, res);
|
||||||
break;
|
break;
|
||||||
case "RIL:SendMMI:Return:OK":
|
case "RIL:SendMMI:Return:OK":
|
||||||
case "RIL:CancelMMI:Return:OK":
|
case "RIL:CancelMMI:Return:OK":
|
||||||
request = this.takeRequest(msg.json.requestId);
|
request = this.takeRequest(msg.json.requestId);
|
||||||
if (request) {
|
if (request) {
|
||||||
Services.DOMRequest.fireSuccess(request, msg.json);
|
Services.DOMRequest.fireSuccess(request, msg.json.result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "RIL:SendMMI:Return:KO":
|
case "RIL:SendMMI:Return:KO":
|
||||||
|
@ -1883,8 +1883,8 @@ let RIL = {
|
|||||||
Buf.simpleRequest(REQUEST_SIGNAL_STRENGTH);
|
Buf.simpleRequest(REQUEST_SIGNAL_STRENGTH);
|
||||||
},
|
},
|
||||||
|
|
||||||
getIMEI: function getIMEI() {
|
getIMEI: function getIMEI(options) {
|
||||||
Buf.simpleRequest(REQUEST_GET_IMEI);
|
Buf.simpleRequest(REQUEST_GET_IMEI, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
getIMEISV: function getIMEISV() {
|
getIMEISV: function getIMEISV() {
|
||||||
@ -2369,8 +2369,16 @@ let RIL = {
|
|||||||
|
|
||||||
// IMEI
|
// IMEI
|
||||||
case MMI_SC_IMEI:
|
case MMI_SC_IMEI:
|
||||||
// TODO: Bug 793189 - MMI Codes: get IMEI.
|
// A device's IMEI can't change, so we only need to request it once.
|
||||||
_sendMMIError("GET_IMEI_NOT_SUPPORTED_VIA_MMI");
|
if (this.IMEI == null) {
|
||||||
|
this.getIMEI({mmi: true});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If we already had the device's IMEI, we just send it to the DOM.
|
||||||
|
options.rilMessageType = "sendMMI";
|
||||||
|
options.success = true;
|
||||||
|
options.result = this.IMEI;
|
||||||
|
this.sendDOMMessage(options);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Call barring
|
// Call barring
|
||||||
@ -4420,11 +4428,20 @@ RIL[REQUEST_SET_CALL_WAITING] = function REQUEST_SET_CALL_WAITING(length, option
|
|||||||
};
|
};
|
||||||
RIL[REQUEST_SMS_ACKNOWLEDGE] = null;
|
RIL[REQUEST_SMS_ACKNOWLEDGE] = null;
|
||||||
RIL[REQUEST_GET_IMEI] = function REQUEST_GET_IMEI(length, options) {
|
RIL[REQUEST_GET_IMEI] = function REQUEST_GET_IMEI(length, options) {
|
||||||
if (options.rilRequestError) {
|
this.IMEI = Buf.readString();
|
||||||
|
// So far we only send the IMEI back to the DOM if it was requested via MMI.
|
||||||
|
if (!options.mmi) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.IMEI = Buf.readString();
|
options.rilMessageType = "sendMMI";
|
||||||
|
options.success = options.rilRequestError == 0;
|
||||||
|
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
||||||
|
if ((!options.success || this.IMEI == null) && !options.errorMsg) {
|
||||||
|
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
|
||||||
|
}
|
||||||
|
options.result = this.IMEI;
|
||||||
|
this.sendDOMMessage(options);
|
||||||
};
|
};
|
||||||
RIL[REQUEST_GET_IMEISV] = function REQUEST_GET_IMEISV(length, options) {
|
RIL[REQUEST_GET_IMEISV] = function REQUEST_GET_IMEISV(length, options) {
|
||||||
if (options.rilRequestError) {
|
if (options.rilRequestError) {
|
||||||
@ -4828,14 +4845,11 @@ RIL[UNSOLICITED_ON_USSD] = function UNSOLICITED_ON_USSD() {
|
|||||||
debug("On USSD. Type Code: " + typeCode + " Message: " + message);
|
debug("On USSD. Type Code: " + typeCode + " Message: " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._ussdSession = (typeCode != "0" || typeCode != "2");
|
this._ussdSession = (typeCode != "0" && typeCode != "2");
|
||||||
|
|
||||||
// Empty message should not be progressed to the DOM.
|
|
||||||
if (!message || message == "") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.sendDOMMessage({rilMessageType: "USSDReceived",
|
this.sendDOMMessage({rilMessageType: "USSDReceived",
|
||||||
message: message});
|
message: message,
|
||||||
|
sessionEnded: !this._ussdSession});
|
||||||
};
|
};
|
||||||
RIL[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED() {
|
RIL[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED() {
|
||||||
let dateString = Buf.readString();
|
let dateString = Buf.readString();
|
||||||
|
@ -324,8 +324,55 @@ add_test(function test_sendMMI_sim_function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
add_test(function test_sendMMI_get_IMEI() {
|
add_test(function test_sendMMI_get_IMEI() {
|
||||||
// TODO: Bug 793189 - MMI Codes: get IMEI
|
let postedMessage;
|
||||||
testSendMMI("*#06#", "GET_IMEI_NOT_SUPPORTED_VIA_MMI");
|
let mmiOptions;
|
||||||
|
let worker = newWorker({
|
||||||
|
postRILMessage: function fakePostRILMessage(data) {
|
||||||
|
},
|
||||||
|
postMessage: function fakePostMessage(message) {
|
||||||
|
postedMessage = message;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
worker.RIL.getIMEI = function getIMEI(options){
|
||||||
|
mmiOptions = options;
|
||||||
|
worker.RIL[REQUEST_SEND_USSD](0, {
|
||||||
|
rilRequestError: ERROR_SUCCESS,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.RIL.sendMMI({mmi: "*#06#"});
|
||||||
|
|
||||||
|
do_check_true(mmiOptions.mmi);
|
||||||
|
do_check_eq (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||||
|
do_check_true(postedMessage.success);
|
||||||
|
|
||||||
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_sendMMI_get_IMEI_error() {
|
||||||
|
let postedMessage;
|
||||||
|
let mmiOptions;
|
||||||
|
let worker = newWorker({
|
||||||
|
postRILMessage: function fakePostRILMessage(data) {
|
||||||
|
},
|
||||||
|
postMessage: function fakePostMessage(message) {
|
||||||
|
postedMessage = message;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
worker.RIL.getIMEI = function getIMEI(options){
|
||||||
|
mmiOptions = options;
|
||||||
|
worker.RIL[REQUEST_SEND_USSD](0, {
|
||||||
|
rilRequestError: ERROR_RADIO_NOT_AVAILABLE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.RIL.sendMMI({mmi: "*#06#"});
|
||||||
|
|
||||||
|
do_check_true(mmiOptions.mmi);
|
||||||
|
do_check_eq (postedMessage.errorMsg, GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||||
|
do_check_false(postedMessage.success);
|
||||||
|
|
||||||
run_next_test();
|
run_next_test();
|
||||||
});
|
});
|
||||||
|
10
dom/webidl/USSDReceivedEvent.webidl
Normal file
10
dom/webidl/USSDReceivedEvent.webidl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dictionary USSDReceivedEventDict {
|
||||||
|
DOMString message = "";
|
||||||
|
boolean sessionEnded = false;
|
||||||
|
};
|
@ -61,6 +61,12 @@ webidl_files += \
|
|||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef MOZ_B2G_RIL
|
||||||
|
webidl_files += \
|
||||||
|
USSDReceivedEvent.webidl \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef ENABLE_TESTS
|
ifdef ENABLE_TESTS
|
||||||
test_webidl_files := \
|
test_webidl_files := \
|
||||||
TestCodeGen.webidl \
|
TestCodeGen.webidl \
|
||||||
|
@ -470,6 +470,17 @@ nsDocShellTreeOwner::Destroy()
|
|||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDocShellTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(double *aScale)
|
||||||
|
{
|
||||||
|
if (mWebBrowser) {
|
||||||
|
return mWebBrowser->GetUnscaledDevicePixelsPerCSSPixel(aScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
*aScale = 1.0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocShellTreeOwner::SetPosition(int32_t aX, int32_t aY)
|
nsDocShellTreeOwner::SetPosition(int32_t aX, int32_t aY)
|
||||||
{
|
{
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user