зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team a=merge CLOSED TREE
This commit is contained in:
Коммит
36bade3e67
|
@ -9,7 +9,7 @@
|
|||
#include "Accessible-inl.h"
|
||||
#include "HyperTextAccessible-inl.h"
|
||||
#include "nsMai.h"
|
||||
|
||||
#include "ProxyAccessible.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Likely.h"
|
||||
|
||||
|
@ -20,15 +20,18 @@ static void
|
|||
setTextContentsCB(AtkEditableText *aText, const gchar *aString)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return;
|
||||
|
||||
NS_ConvertUTF8toUTF16 strContent(aString);
|
||||
text->ReplaceText(strContent);
|
||||
NS_ConvertUTF8toUTF16 strContent(aString);
|
||||
text->ReplaceText(strContent);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
NS_ConvertUTF8toUTF16 strContent(aString);
|
||||
proxy->ReplaceText(strContent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -36,71 +39,82 @@ insertTextCB(AtkEditableText *aText,
|
|||
const gchar *aString, gint aLength, gint *aPosition)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return;
|
||||
|
||||
NS_ConvertUTF8toUTF16 strContent(aString, aLength);
|
||||
text->InsertText(strContent, *aPosition);
|
||||
NS_ConvertUTF8toUTF16 strContent(aString);
|
||||
text->InsertText(strContent, *aPosition);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
NS_ConvertUTF8toUTF16 strContent(aString);
|
||||
proxy->InsertText(strContent, *aPosition);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copyTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return;
|
||||
|
||||
text->CopyText(aStartPos, aEndPos);
|
||||
text->CopyText(aStartPos, aEndPos);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
proxy->CopyText(aStartPos, aEndPos);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cutTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return;
|
||||
|
||||
text->CutText(aStartPos, aEndPos);
|
||||
text->CutText(aStartPos, aEndPos);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
proxy->CutText(aStartPos, aEndPos);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deleteTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return;
|
||||
|
||||
text->DeleteText(aStartPos, aEndPos);
|
||||
text->DeleteText(aStartPos, aEndPos);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
proxy->DeleteText(aStartPos, aEndPos);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pasteTextCB(AtkEditableText *aText, gint aPosition)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return;
|
||||
|
||||
text->PasteText(aPosition);
|
||||
text->PasteText(aPosition);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
proxy->PasteText(aPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -478,20 +478,28 @@ getTextSelectionCB(AtkText *aText, gint aSelectionNum,
|
|||
gint *aStartOffset, gint *aEndOffset)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return nullptr;
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return nullptr;
|
||||
|
||||
int32_t startOffset = 0, endOffset = 0;
|
||||
text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset);
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset);
|
||||
*aStartOffset = startOffset;
|
||||
*aEndOffset = endOffset;
|
||||
|
||||
return getTextCB(aText, *aStartOffset, *aEndOffset);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
nsString data;
|
||||
proxy->SelectionBoundsAt(aSelectionNum, data, &startOffset, &endOffset);
|
||||
*aStartOffset = startOffset;
|
||||
*aEndOffset = endOffset;
|
||||
|
||||
NS_ConvertUTF16toUTF8 dataAsUTF8(data);
|
||||
return (dataAsUTF8.get()) ? g_strdup(dataAsUTF8.get()) : nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// set methods
|
||||
|
@ -501,14 +509,18 @@ addTextSelectionCB(AtkText *aText,
|
|||
gint aEndOffset)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return FALSE;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return FALSE;
|
||||
return text->AddToSelection(aStartOffset, aEndOffset);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
return proxy->AddToSelection(aStartOffset, aEndOffset);
|
||||
}
|
||||
|
||||
return text->AddToSelection(aStartOffset, aEndOffset);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -516,14 +528,18 @@ removeTextSelectionCB(AtkText *aText,
|
|||
gint aSelectionNum)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return FALSE;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return FALSE;
|
||||
return text->RemoveFromSelection(aSelectionNum);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
return proxy->RemoveFromSelection(aSelectionNum);
|
||||
}
|
||||
|
||||
return text->RemoveFromSelection(aSelectionNum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -531,14 +547,18 @@ setTextSelectionCB(AtkText *aText, gint aSelectionNum,
|
|||
gint aStartOffset, gint aEndOffset)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
if (!accWrap)
|
||||
return FALSE;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole())
|
||||
return FALSE;
|
||||
return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
return proxy->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
|
||||
}
|
||||
|
||||
return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -407,5 +407,182 @@ DocAccessibleChild::RecvOffsetAtPoint(const uint64_t& aID,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvSelectionBoundsAt(const uint64_t& aID,
|
||||
const int32_t& aSelectionNum,
|
||||
bool* aSucceeded,
|
||||
nsString* aData,
|
||||
int32_t* aStartOffset,
|
||||
int32_t* aEndOffset)
|
||||
{
|
||||
*aSucceeded = false;
|
||||
*aStartOffset = 0;
|
||||
*aEndOffset = 0;
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
*aSucceeded =
|
||||
acc->SelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
|
||||
if (*aSucceeded) {
|
||||
acc->TextSubstring(*aStartOffset, *aEndOffset, *aData);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvSetSelectionBoundsAt(const uint64_t& aID,
|
||||
const int32_t& aSelectionNum,
|
||||
const int32_t& aStartOffset,
|
||||
const int32_t& aEndOffset,
|
||||
bool* aSucceeded)
|
||||
{
|
||||
*aSucceeded = false;
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
*aSucceeded =
|
||||
acc->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvAddToSelection(const uint64_t& aID,
|
||||
const int32_t& aStartOffset,
|
||||
const int32_t& aEndOffset,
|
||||
bool* aSucceeded)
|
||||
{
|
||||
*aSucceeded = false;
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
*aSucceeded = acc->AddToSelection(aStartOffset, aEndOffset);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvRemoveFromSelection(const uint64_t& aID,
|
||||
const int32_t& aSelectionNum,
|
||||
bool* aSucceeded)
|
||||
{
|
||||
*aSucceeded = false;
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
*aSucceeded = acc->RemoveFromSelection(aSelectionNum);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvScrollSubstringTo(const uint64_t& aID,
|
||||
const int32_t& aStartOffset,
|
||||
const int32_t& aEndOffset,
|
||||
const uint32_t& aScrollType)
|
||||
{
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc) {
|
||||
acc->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvScrollSubstringToPoint(const uint64_t& aID,
|
||||
const int32_t& aStartOffset,
|
||||
const int32_t& aEndOffset,
|
||||
const uint32_t& aCoordinateType,
|
||||
const int32_t& aX,
|
||||
const int32_t& aY)
|
||||
{
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc) {
|
||||
acc->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType,
|
||||
aX, aY);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvReplaceText(const uint64_t& aID,
|
||||
const nsString& aText)
|
||||
{
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
acc->ReplaceText(aText);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvInsertText(const uint64_t& aID,
|
||||
const nsString& aText,
|
||||
const int32_t& aPosition)
|
||||
{
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
acc->InsertText(aText, aPosition);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvCopyText(const uint64_t& aID,
|
||||
const int32_t& aStartPos,
|
||||
const int32_t& aEndPos)
|
||||
{
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
acc->CopyText(aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvCutText(const uint64_t& aID,
|
||||
const int32_t& aStartPos,
|
||||
const int32_t& aEndPos)
|
||||
{
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
acc->CutText(aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvDeleteText(const uint64_t& aID,
|
||||
const int32_t& aStartPos,
|
||||
const int32_t& aEndPos)
|
||||
{
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
acc->DeleteText(aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvPasteText(const uint64_t& aID,
|
||||
const int32_t& aPosition)
|
||||
{
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
if (acc && acc->IsTextRole()) {
|
||||
acc->PasteText(aPosition);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,6 +127,63 @@ public:
|
|||
const int32_t& aY,
|
||||
const uint32_t& aCoordType,
|
||||
int32_t* aRetVal) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvSelectionBoundsAt(const uint64_t& aID,
|
||||
const int32_t& aSelectionNum,
|
||||
bool* aSucceeded,
|
||||
nsString* aData,
|
||||
int32_t* aStartOffset,
|
||||
int32_t* aEndOffset) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvSetSelectionBoundsAt(const uint64_t& aID,
|
||||
const int32_t& aSelectionNum,
|
||||
const int32_t& aStartOffset,
|
||||
const int32_t& aEndOffset,
|
||||
bool* aSucceeded) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvAddToSelection(const uint64_t& aID,
|
||||
const int32_t& aStartOffset,
|
||||
const int32_t& aEndOffset,
|
||||
bool* aSucceeded) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvRemoveFromSelection(const uint64_t& aID,
|
||||
const int32_t& aSelectionNum,
|
||||
bool* aSucceeded) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvScrollSubstringTo(const uint64_t& aID,
|
||||
const int32_t& aStartOffset,
|
||||
const int32_t& aEndOffset,
|
||||
const uint32_t& aScrollType) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvScrollSubstringToPoint(const uint64_t& aID,
|
||||
const int32_t& aStartOffset,
|
||||
const int32_t& aEndOffset,
|
||||
const uint32_t& aCoordinateType,
|
||||
const int32_t& aX,
|
||||
const int32_t& aY) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvReplaceText(const uint64_t& aID,
|
||||
const nsString& aText);
|
||||
|
||||
virtual bool RecvInsertText(const uint64_t& aID,
|
||||
const nsString& aText,
|
||||
const int32_t& aPosition);
|
||||
|
||||
virtual bool RecvCopyText(const uint64_t& aID,
|
||||
const int32_t& aStartPos,
|
||||
const int32_t& aEndPos);
|
||||
|
||||
virtual bool RecvCutText(const uint64_t& aID,
|
||||
const int32_t& aStartPos,
|
||||
const int32_t& aEndPos);
|
||||
|
||||
virtual bool RecvDeleteText(const uint64_t& aID,
|
||||
const int32_t& aStartPos,
|
||||
const int32_t& aEndPos);
|
||||
|
||||
virtual bool RecvPasteText(const uint64_t& aID,
|
||||
const int32_t& aPosition);
|
||||
|
||||
private:
|
||||
bool PersistentPropertiesToArray(nsIPersistentProperties* aProps,
|
||||
nsTArray<Attribute>* aAttributes);
|
||||
|
|
|
@ -96,6 +96,31 @@ child:
|
|||
|
||||
prio(high) sync OffsetAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aCoordType)
|
||||
returns(int32_t aRetVal);
|
||||
|
||||
prio(high) sync SelectionBoundsAt(uint64_t aID, int32_t aSelectionNum)
|
||||
returns(bool aSucceeded, nsString aData, int32_t aStartOffset, int32_t aEndOffset);
|
||||
prio(high) sync SetSelectionBoundsAt(uint64_t aID, int32_t aSelectionNum,
|
||||
int32_t aStartOffset, int32_t aEndOffset)
|
||||
returns(bool aSucceeded);
|
||||
prio(high) sync AddToSelection(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset)
|
||||
returns(bool aSucceeded);
|
||||
prio(high) sync RemoveFromSelection(uint64_t aID, int32_t aSelectionNum)
|
||||
returns(bool aSucceeded);
|
||||
|
||||
ScrollSubstringTo(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
|
||||
uint32_t aScrollType);
|
||||
ScrollSubstringToPoint(uint64_t aID,
|
||||
int32_t aStartOffset,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aCoordinateType,
|
||||
int32_t aX, int32_t aY);
|
||||
|
||||
prio(high) sync ReplaceText(uint64_t aID, nsString aText);
|
||||
prio(high) sync InsertText(uint64_t aID, nsString aText, int32_t aPosition);
|
||||
prio(high) sync CopyText(uint64_t aID, int32_t aStartPos, int32_t aEndPos);
|
||||
prio(high) sync CutText(uint64_t aID, int32_t aStartPos, int32_t aEndPos);
|
||||
prio(high) sync DeleteText(uint64_t aID, int32_t aStartPos, int32_t aEndPos);
|
||||
prio(high) sync PasteText(uint64_t aID, int32_t aPosition);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -270,5 +270,98 @@ ProxyAccessible::OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType)
|
|||
return retVal;
|
||||
}
|
||||
|
||||
bool
|
||||
ProxyAccessible::SelectionBoundsAt(int32_t aSelectionNum,
|
||||
nsString& aData,
|
||||
int32_t* aStartOffset,
|
||||
int32_t* aEndOffset)
|
||||
{
|
||||
bool retVal = false;
|
||||
unused << mDoc->SendSelectionBoundsAt(mID, aSelectionNum, &retVal, &aData,
|
||||
aStartOffset, aEndOffset);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool
|
||||
ProxyAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
|
||||
int32_t aStartOffset,
|
||||
int32_t aEndOffset)
|
||||
{
|
||||
bool retVal = false;
|
||||
unused << mDoc->SendSetSelectionBoundsAt(mID, aSelectionNum, aStartOffset,
|
||||
aEndOffset, &retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool
|
||||
ProxyAccessible::AddToSelection(int32_t aStartOffset,
|
||||
int32_t aEndOffset)
|
||||
{
|
||||
bool retVal = false;
|
||||
unused << mDoc->SendAddToSelection(mID, aStartOffset, aEndOffset, &retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool
|
||||
ProxyAccessible::RemoveFromSelection(int32_t aSelectionNum)
|
||||
{
|
||||
bool retVal = false;
|
||||
unused << mDoc->SendRemoveFromSelection(mID, aSelectionNum, &retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
|
||||
uint32_t aScrollType)
|
||||
{
|
||||
unused << mDoc->SendScrollSubstringTo(mID, aStartOffset, aEndOffset, aScrollType);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aCoordinateType,
|
||||
int32_t aX, int32_t aY)
|
||||
{
|
||||
unused << mDoc->SendScrollSubstringToPoint(mID, aStartOffset, aEndOffset,
|
||||
aCoordinateType, aX, aY);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::ReplaceText(const nsString& aText)
|
||||
{
|
||||
unused << mDoc->SendReplaceText(mID, aText);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::InsertText(const nsString& aText, int32_t aPosition)
|
||||
{
|
||||
unused << mDoc->SendInsertText(mID, aText, aPosition);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::CopyText(int32_t aStartPos, int32_t aEndPos)
|
||||
{
|
||||
unused << mDoc->SendCopyText(mID, aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::CutText(int32_t aStartPos, int32_t aEndPos)
|
||||
{
|
||||
unused << mDoc->SendCutText(mID, aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::DeleteText(int32_t aStartPos, int32_t aEndPos)
|
||||
{
|
||||
unused << mDoc->SendDeleteText(mID, aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::PasteText(int32_t aPosition)
|
||||
{
|
||||
unused << mDoc->SendPasteText(mID, aPosition);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,6 +140,40 @@ public:
|
|||
|
||||
int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
|
||||
|
||||
bool SelectionBoundsAt(int32_t aSelectionNum,
|
||||
nsString& aData,
|
||||
int32_t* aStartOffset,
|
||||
int32_t* aEndOffset);
|
||||
|
||||
bool SetSelectionBoundsAt(int32_t aSelectionNum,
|
||||
int32_t aStartOffset,
|
||||
int32_t aEndOffset);
|
||||
|
||||
bool AddToSelection(int32_t aStartOffset,
|
||||
int32_t aEndOffset);
|
||||
|
||||
bool RemoveFromSelection(int32_t aSelectionNum);
|
||||
|
||||
void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
|
||||
uint32_t aScrollType);
|
||||
|
||||
void ScrollSubstringToPoint(int32_t aStartOffset,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aCoordinateType,
|
||||
int32_t aX, int32_t aY);
|
||||
|
||||
void ReplaceText(const nsString& aText);
|
||||
|
||||
void InsertText(const nsString& aText, int32_t aPosition);
|
||||
|
||||
void CopyText(int32_t aStartPos, int32_t aEndPos);
|
||||
|
||||
void CutText(int32_t aStartPos, int32_t aEndPos);
|
||||
|
||||
void DeleteText(int32_t aStartPos, int32_t aEndPos);
|
||||
|
||||
void PasteText(int32_t aPosition);
|
||||
|
||||
/**
|
||||
* Allow the platform to store a pointers worth of data on us.
|
||||
*/
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ddf33f81e9a60f8110fcfd6b51b5dff2db676183"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -125,7 +125,7 @@
|
|||
<!-- Flame specific things -->
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
|
||||
<project name="device/qcom/common" path="device/qcom/common" revision="2501e5940ba69ece7654ff85611c76ae5bda299c"/>
|
||||
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="e7c90613521145db090dd24147afd5ceb5703190"/>
|
||||
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="ebad7da532429a6f5efadc00bf6ad8a41288a429"/>
|
||||
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0865bc4134b67220df4058625fba29305d6b10c3"/>
|
||||
<project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="fda40423ffa573dc6cafd3780515010cb2a086be"/>
|
||||
<project name="platform_bootable_recovery" path="bootable/recovery" remote="b2g" revision="26e78a979f3090dc196219e268467620b6c40ec5"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ddf33f81e9a60f8110fcfd6b51b5dff2db676183"/>
|
||||
|
@ -121,7 +121,7 @@
|
|||
<!-- Flame specific things -->
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="e8a318f7690092e639ba88891606f4183e846d3f"/>
|
||||
<project name="device/qcom/common" path="device/qcom/common" revision="878804e0becfe5635bb8ccbf2671333d546c6fb6"/>
|
||||
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="c76af2b3c4acb7062bc928169cd303451b88092e"/>
|
||||
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="f54de260816110dca21bc9e76e4c4a09a950f232"/>
|
||||
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="49417cfc622074daa3c76b345a199f6731375800"/>
|
||||
<project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="6f00133ac0f47e90027bd7e263a16b405bfac503"/>
|
||||
<project name="platform_bootable_recovery" path="bootable/recovery" remote="b2g" revision="e81502511cda303c803e63f049574634bc96f9f2"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69",
|
||||
"git_revision": "943c8b4039f59b08ba100390e164a076a20c892e",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "96b7e916f53ebcd185b087338913edb5ffdadade",
|
||||
"revision": "c8f9d4bbb0ab4ddfb272c0ee955e640b9d122b54",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ddf33f81e9a60f8110fcfd6b51b5dff2db676183"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f6a1fcd30ee6a286f3bca9d0c3cb600e21bfbf69"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="943c8b4039f59b08ba100390e164a076a20c892e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -185,6 +185,9 @@
|
|||
#ifdef MOZ_B2G_BT
|
||||
@RESPATH@/components/dom_bluetooth.xpt
|
||||
#endif
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
@BINPATH@/components/dom_camera.xpt
|
||||
#endif
|
||||
@RESPATH@/components/dom_canvas.xpt
|
||||
@RESPATH@/components/dom_contacts.xpt
|
||||
@RESPATH@/components/dom_alarm.xpt
|
||||
|
@ -456,6 +459,12 @@
|
|||
@RESPATH@/components/WifiWorker.manifest
|
||||
#endif // MOZ_WIDGET_GONK
|
||||
|
||||
; Camera
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
@BINPATH@/components/CameraTestHardware.js
|
||||
@BINPATH@/components/CameraTestHardware.manifest
|
||||
#endif // MOZ_B2G_CAMERA
|
||||
|
||||
; Tethering
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@RESPATH@/components/TetheringManager.js
|
||||
|
|
|
@ -1779,6 +1779,14 @@ pref("geo.provider.use_corelocation", true);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#ifdef RELEASE_BUILD
|
||||
pref("geo.provider.ms-windows-location", false);
|
||||
#else
|
||||
pref("geo.provider.ms-windows-location", true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Necko IPC security checks only needed for app isolation for cookies/cache/etc:
|
||||
// currently irrelevant for desktop e10s
|
||||
pref("network.disable.ipc.security", true);
|
||||
|
|
|
@ -537,9 +537,6 @@
|
|||
@RESPATH@/components/Webapps.manifest
|
||||
@RESPATH@/components/AppsService.js
|
||||
@RESPATH@/components/AppsService.manifest
|
||||
@RESPATH@/components/nsDOMIdentity.js
|
||||
@RESPATH@/components/nsIDService.js
|
||||
@RESPATH@/components/Identity.manifest
|
||||
@RESPATH@/components/recording-cmdline.js
|
||||
@RESPATH@/components/recording-cmdline.manifest
|
||||
@RESPATH@/components/htmlMenuBuilder.js
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
== bug456008.xhtml bug456008-ref.html
|
||||
== bug439965.html bug439965-ref.html
|
||||
== bug427779.xml bug427779-ref.xml
|
||||
skip-if(B2G) == bug559996.html bug559996-ref.html # bug 773482
|
||||
skip-if(B2G) == bug591981-1.html bug591981-ref.html
|
||||
skip-if(B2G||Mulet) == bug559996.html bug559996-ref.html # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == bug591981-1.html bug591981-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
== bug591981-2.html bug591981-ref.html
|
||||
== bug592366-1.html bug592366-ref.html
|
||||
skip-if(B2G) == bug592366-2.html bug592366-ref.html
|
||||
skip-if(B2G&&browserIsRemote) == bug592366-1.xhtml bug592366-ref.xhtml
|
||||
skip-if(B2G) == bug592366-2.xhtml bug592366-ref.xhtml
|
||||
skip-if(B2G||Mulet) == bug592366-2.html bug592366-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == bug592366-1.xhtml bug592366-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == bug592366-2.xhtml bug592366-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
== bug798068.xhtml bug798068-ref.xhtml
|
||||
|
|
|
@ -39,6 +39,8 @@ enum StructuredCloneTags {
|
|||
SCTAG_DOM_SYSTEM_PRINCIPAL,
|
||||
SCTAG_DOM_CONTENT_PRINCIPAL,
|
||||
|
||||
SCTAG_DOM_NFC_NDEF,
|
||||
|
||||
SCTAG_DOM_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -3187,7 +3187,7 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugin
|
|||
}
|
||||
|
||||
static void
|
||||
MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
|
||||
MaybeReflowForInflationScreenSizeChange(nsPresContext *aPresContext)
|
||||
{
|
||||
if (aPresContext) {
|
||||
nsIPresShell* presShell = aPresContext->GetPresShell();
|
||||
|
@ -3196,7 +3196,7 @@ MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
|
|||
bool changed = false;
|
||||
if (presShell && presShell->FontSizeInflationEnabled() &&
|
||||
presShell->FontSizeInflationMinTwips() != 0) {
|
||||
aPresContext->ScreenWidthInchesForFontInflation(&changed);
|
||||
aPresContext->ScreenSizeInchesForFontInflation(&changed);
|
||||
}
|
||||
|
||||
changed = changed ||
|
||||
|
@ -3254,7 +3254,7 @@ nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aH
|
|||
// size also changes, we hook in the needed updates here rather
|
||||
// than adding a separate notification just for this change.
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
MaybeReflowForInflationScreenWidthChange(presContext);
|
||||
MaybeReflowForInflationScreenSizeChange(presContext);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -575,8 +575,6 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
|
|||
mRunningTimeout(nullptr), mMutationBits(0), mIsDocumentLoaded(false),
|
||||
mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
|
||||
mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
|
||||
mMayHaveTouchCaret(false),
|
||||
mMayHaveScrollWheelEventListener(false),
|
||||
mMayHaveMouseEnterLeaveEventListener(false),
|
||||
mMayHavePointerEnterLeaveEventListener(false),
|
||||
mIsModalContentWindow(false),
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
#include "mozilla/dom/ErrorEvent.h"
|
||||
#include "mozilla/dom/ImageDataBinding.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#ifdef MOZ_NFC
|
||||
#include "mozilla/dom/MozNDEFRecord.h"
|
||||
#endif // MOZ_NFC
|
||||
#include "mozilla/dom/StructuredClone.h"
|
||||
#include "mozilla/dom/SubtleCryptoBinding.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
|
@ -2514,6 +2517,24 @@ NS_DOMReadStructuredClone(JSContext* cx,
|
|||
}
|
||||
|
||||
return result.toObjectOrNull();
|
||||
} else if (tag == SCTAG_DOM_NFC_NDEF) {
|
||||
#ifdef MOZ_NFC
|
||||
nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(cx));
|
||||
if (!global) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Prevent the return value from being trashed by a GC during ~nsRefPtr.
|
||||
JS::Rooted<JSObject*> result(cx);
|
||||
{
|
||||
nsRefPtr<MozNDEFRecord> ndefRecord = new MozNDEFRecord(global);
|
||||
result = ndefRecord->ReadStructuredClone(cx, reader) ?
|
||||
ndefRecord->WrapObject(cx) : nullptr;
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Don't know what this is. Bail.
|
||||
|
@ -2565,6 +2586,14 @@ NS_DOMWriteStructuredClone(JSContext* cx,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_NFC
|
||||
MozNDEFRecord* ndefRecord;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(MozNDEFRecord, obj, ndefRecord))) {
|
||||
return JS_WriteUint32Pair(writer, SCTAG_DOM_NFC_NDEF, 0) &&
|
||||
ndefRecord->WriteStructuredClone(cx, writer);
|
||||
}
|
||||
#endif // MOZ_NFC
|
||||
|
||||
// Don't know what this is
|
||||
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return false;
|
||||
|
|
|
@ -430,9 +430,6 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
|||
if (elm->MayHaveTouchEventListener()) {
|
||||
window->SetHasTouchEventListeners();
|
||||
}
|
||||
if (elm->MayHaveScrollWheelEventListener()) {
|
||||
window->SetHasScrollWheelEventListeners();
|
||||
}
|
||||
if (elm->MayHaveMouseEnterLeaveEventListener()) {
|
||||
window->SetHasMouseEnterLeaveEventListeners();
|
||||
}
|
||||
|
|
|
@ -443,44 +443,6 @@ public:
|
|||
return mMayHaveTouchEventListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to indicate that some node (this window, its document,
|
||||
* or content in that document) has a scroll wheel event listener.
|
||||
*/
|
||||
void SetHasScrollWheelEventListeners()
|
||||
{
|
||||
mMayHaveScrollWheelEventListener = true;
|
||||
}
|
||||
|
||||
bool HasScrollWheelEventListeners()
|
||||
{
|
||||
return mMayHaveScrollWheelEventListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not any event listeners are present that APZ must be
|
||||
* aware of.
|
||||
*/
|
||||
bool HasApzAwareEventListeners()
|
||||
{
|
||||
return HasTouchEventListeners() || HasScrollWheelEventListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be called when touch caret visibility has changed. mMayHaveTouchCaret
|
||||
* is set if that some node (this window, its document, or content in that
|
||||
* document) has a visible touch caret.
|
||||
*/
|
||||
void SetMayHaveTouchCaret(bool aSetValue)
|
||||
{
|
||||
mMayHaveTouchCaret = aSetValue;
|
||||
}
|
||||
|
||||
bool MayHaveTouchCaret()
|
||||
{
|
||||
return mMayHaveTouchCaret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the top-level window into fullscreen mode if aIsFullScreen is true,
|
||||
* otherwise exits fullscreen. If aRequireTrust is true, this method only
|
||||
|
@ -802,8 +764,6 @@ protected:
|
|||
bool mIsInnerWindow;
|
||||
bool mMayHavePaintEventListener;
|
||||
bool mMayHaveTouchEventListener;
|
||||
bool mMayHaveTouchCaret;
|
||||
bool mMayHaveScrollWheelEventListener;
|
||||
bool mMayHaveMouseEnterLeaveEventListener;
|
||||
bool mMayHavePointerEnterLeaveEventListener;
|
||||
|
||||
|
|
|
@ -209,6 +209,16 @@
|
|||
// Test to ensure that we don't pass CPOWs to C++-implemented interfaces.
|
||||
// See bug 1072980.
|
||||
if (test_state == "remote") {
|
||||
// This doesn't work because we intercept toString specially
|
||||
// and don't cache the function pointer.
|
||||
// See bug 1140636.
|
||||
todo_is(savedElement.toString, savedElement.toString, "toString identity works");
|
||||
|
||||
// This does work because we create a CPOW for isEqualNode that stays
|
||||
// alive as long as we have a reference to the first CPOW (so as long
|
||||
// as it's detectable).
|
||||
is(savedElement.isEqualNode, savedElement.isEqualNode, "webidl function identity works");
|
||||
|
||||
let walker = Components.classes["@mozilla.org/inspector/deep-tree-walker;1"]
|
||||
.createInstance(Components.interfaces.inIDeepTreeWalker);
|
||||
const SHOW_ELEMENT = Components.interfaces.nsIDOMNodeFilter.SHOW_ELEMENT;
|
||||
|
|
|
@ -2865,14 +2865,24 @@ private:
|
|||
typename Conditional<IsRefcounted<T>::value, nsRefPtr<T>, OwnedNative>::Type mNative;
|
||||
};
|
||||
|
||||
template<class T,
|
||||
bool isISupports=IsBaseOf<nsISupports, T>::value>
|
||||
class DeferredFinalizer
|
||||
template<class T>
|
||||
struct DeferredFinalizerImpl
|
||||
{
|
||||
typedef typename Conditional<IsRefcounted<T>::value,
|
||||
nsRefPtr<T>, nsAutoPtr<T>>::Type SmartPtr;
|
||||
typedef typename Conditional<IsSame<T, nsISupports>::value,
|
||||
nsCOMPtr<T>,
|
||||
typename Conditional<IsRefcounted<T>::value,
|
||||
nsRefPtr<T>,
|
||||
nsAutoPtr<T>>::Type>::Type SmartPtr;
|
||||
typedef nsTArray<SmartPtr> SmartPtrArray;
|
||||
|
||||
static_assert(IsSame<T, nsISupports>::value || !IsBaseOf<nsISupports, T>::value,
|
||||
"nsISupports classes should all use the nsISupports instantiation");
|
||||
|
||||
static inline void
|
||||
AppendAndTake(nsTArray<nsCOMPtr<nsISupports>>& smartPtrArray, nsISupports* ptr)
|
||||
{
|
||||
smartPtrArray.AppendElement(dont_AddRef(ptr));
|
||||
}
|
||||
template<class U>
|
||||
static inline void
|
||||
AppendAndTake(nsTArray<nsRefPtr<U>>& smartPtrArray, U* ptr)
|
||||
|
@ -2913,20 +2923,24 @@ class DeferredFinalizer
|
|||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
template<class T,
|
||||
bool isISupports=IsBaseOf<nsISupports, T>::value>
|
||||
struct DeferredFinalizer
|
||||
{
|
||||
static void
|
||||
AddForDeferredFinalization(T* aObject)
|
||||
{
|
||||
cyclecollector::DeferredFinalize(AppendDeferredFinalizePointer,
|
||||
DeferredFinalize, aObject);
|
||||
typedef DeferredFinalizerImpl<T> Impl;
|
||||
cyclecollector::DeferredFinalize(Impl::AppendDeferredFinalizePointer,
|
||||
Impl::DeferredFinalize, aObject);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class DeferredFinalizer<T, true>
|
||||
struct DeferredFinalizer<T, true>
|
||||
{
|
||||
public:
|
||||
static void
|
||||
AddForDeferredFinalization(T* aObject)
|
||||
{
|
||||
|
|
|
@ -23,11 +23,13 @@ public:
|
|||
}
|
||||
|
||||
static BluetoothHidManager* Get();
|
||||
virtual ~BluetoothHidManager();
|
||||
|
||||
// HID-specific functions
|
||||
void HandleInputPropertyChanged(const BluetoothSignal& aSignal);
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothHidManager();
|
||||
|
||||
private:
|
||||
BluetoothHidManager();
|
||||
bool Init();
|
||||
|
|
|
@ -21,8 +21,6 @@ class BluetoothSocketResultHandler
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothSocketResultHandler)
|
||||
|
||||
virtual ~BluetoothSocketResultHandler() { }
|
||||
|
||||
virtual void OnError(BluetoothStatus aStatus)
|
||||
{
|
||||
BT_WARNING("Received error code %d", (int)aStatus);
|
||||
|
@ -33,6 +31,9 @@ public:
|
|||
int aConnectionState) { }
|
||||
virtual void Accept(int aSockFd, const nsAString& aBdAddress,
|
||||
int aConnectionState) { }
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothSocketResultHandler() { }
|
||||
};
|
||||
|
||||
class BluetoothSocketInterface
|
||||
|
@ -67,8 +68,6 @@ protected:
|
|||
class BluetoothHandsfreeNotificationHandler
|
||||
{
|
||||
public:
|
||||
virtual ~BluetoothHandsfreeNotificationHandler();
|
||||
|
||||
virtual void
|
||||
ConnectionStateNotification(BluetoothHandsfreeConnectionState aState,
|
||||
const nsAString& aBdAddr)
|
||||
|
@ -151,6 +150,8 @@ public:
|
|||
protected:
|
||||
BluetoothHandsfreeNotificationHandler()
|
||||
{ }
|
||||
|
||||
virtual ~BluetoothHandsfreeNotificationHandler();
|
||||
};
|
||||
|
||||
class BluetoothHandsfreeResultHandler
|
||||
|
@ -158,8 +159,6 @@ class BluetoothHandsfreeResultHandler
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothHandsfreeResultHandler)
|
||||
|
||||
virtual ~BluetoothHandsfreeResultHandler() { }
|
||||
|
||||
virtual void OnError(BluetoothStatus aStatus)
|
||||
{
|
||||
BT_WARNING("Received error code %d", (int)aStatus);
|
||||
|
@ -188,6 +187,9 @@ public:
|
|||
virtual void PhoneStateChange() { }
|
||||
|
||||
virtual void ConfigureWbs() { }
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothHandsfreeResultHandler() { }
|
||||
};
|
||||
|
||||
class BluetoothHandsfreeInterface
|
||||
|
@ -277,8 +279,6 @@ protected:
|
|||
class BluetoothA2dpNotificationHandler
|
||||
{
|
||||
public:
|
||||
virtual ~BluetoothA2dpNotificationHandler();
|
||||
|
||||
virtual void
|
||||
ConnectionStateNotification(BluetoothA2dpConnectionState aState,
|
||||
const nsAString& aBdAddr)
|
||||
|
@ -298,6 +298,8 @@ public:
|
|||
protected:
|
||||
BluetoothA2dpNotificationHandler()
|
||||
{ }
|
||||
|
||||
virtual ~BluetoothA2dpNotificationHandler();
|
||||
};
|
||||
|
||||
class BluetoothA2dpResultHandler
|
||||
|
@ -305,8 +307,6 @@ class BluetoothA2dpResultHandler
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothA2dpResultHandler)
|
||||
|
||||
virtual ~BluetoothA2dpResultHandler() { }
|
||||
|
||||
virtual void OnError(BluetoothStatus aStatus)
|
||||
{
|
||||
BT_WARNING("Received error code %d", (int)aStatus);
|
||||
|
@ -316,6 +316,9 @@ public:
|
|||
virtual void Cleanup() { }
|
||||
virtual void Connect() { }
|
||||
virtual void Disconnect() { }
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothA2dpResultHandler() { }
|
||||
};
|
||||
|
||||
class BluetoothA2dpInterface
|
||||
|
@ -342,8 +345,6 @@ protected:
|
|||
class BluetoothAvrcpNotificationHandler
|
||||
{
|
||||
public:
|
||||
virtual ~BluetoothAvrcpNotificationHandler();
|
||||
|
||||
virtual void
|
||||
GetPlayStatusNotification()
|
||||
{ }
|
||||
|
@ -400,6 +401,8 @@ public:
|
|||
protected:
|
||||
BluetoothAvrcpNotificationHandler()
|
||||
{ }
|
||||
|
||||
virtual ~BluetoothAvrcpNotificationHandler();
|
||||
};
|
||||
|
||||
class BluetoothAvrcpResultHandler
|
||||
|
@ -407,8 +410,6 @@ class BluetoothAvrcpResultHandler
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothAvrcpResultHandler)
|
||||
|
||||
virtual ~BluetoothAvrcpResultHandler() { }
|
||||
|
||||
virtual void OnError(BluetoothStatus aStatus)
|
||||
{
|
||||
BT_WARNING("Received error code %d", (int)aStatus);
|
||||
|
@ -433,6 +434,9 @@ public:
|
|||
virtual void RegisterNotificationRsp() { }
|
||||
|
||||
virtual void SetVolume() { }
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothAvrcpResultHandler() { }
|
||||
};
|
||||
|
||||
class BluetoothAvrcpInterface
|
||||
|
@ -491,8 +495,6 @@ protected:
|
|||
class BluetoothNotificationHandler
|
||||
{
|
||||
public:
|
||||
virtual ~BluetoothNotificationHandler();
|
||||
|
||||
virtual void AdapterStateChangedNotification(bool aState) { }
|
||||
virtual void AdapterPropertiesNotification(
|
||||
BluetoothStatus aStatus, int aNumProperties,
|
||||
|
@ -533,6 +535,8 @@ public:
|
|||
protected:
|
||||
BluetoothNotificationHandler()
|
||||
{ }
|
||||
|
||||
virtual ~BluetoothNotificationHandler();
|
||||
};
|
||||
|
||||
class BluetoothResultHandler
|
||||
|
@ -540,8 +544,6 @@ class BluetoothResultHandler
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothResultHandler)
|
||||
|
||||
virtual ~BluetoothResultHandler() { }
|
||||
|
||||
virtual void OnError(BluetoothStatus aStatus)
|
||||
{
|
||||
BT_LOGR("Received error code %d", aStatus);
|
||||
|
@ -581,6 +583,9 @@ public:
|
|||
virtual void LeTestMode() { }
|
||||
|
||||
virtual void ReadEnergyInfo() { }
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothResultHandler() { }
|
||||
};
|
||||
|
||||
class BluetoothInterface
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
MOZ_ASSERT(aController);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~CheckProfileStatusCallback()
|
||||
{
|
||||
mController = nullptr;
|
||||
|
|
|
@ -33,11 +33,12 @@ class BluetoothProfileResultHandler
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothProfileResultHandler);
|
||||
|
||||
virtual ~BluetoothProfileResultHandler() { }
|
||||
|
||||
virtual void OnError(nsresult aResult) { }
|
||||
virtual void Init() { }
|
||||
virtual void Deinit() { }
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothProfileResultHandler() { }
|
||||
};
|
||||
|
||||
class BluetoothProfileManagerBase : public nsIObserver
|
||||
|
|
|
@ -27,11 +27,13 @@ public:
|
|||
NS_DECL_NSIICCLISTENER
|
||||
|
||||
IccListener() { }
|
||||
virtual ~IccListener() { }
|
||||
|
||||
bool Listen(bool aStart);
|
||||
void SetOwner(BluetoothRilListener *aOwner);
|
||||
|
||||
protected:
|
||||
virtual ~IccListener() { }
|
||||
|
||||
private:
|
||||
BluetoothRilListener* mOwner;
|
||||
};
|
||||
|
@ -44,10 +46,12 @@ public:
|
|||
|
||||
MobileConnectionListener(uint32_t aClientId)
|
||||
: mClientId(aClientId) { }
|
||||
virtual ~MobileConnectionListener() { }
|
||||
|
||||
bool Listen(bool aStart);
|
||||
|
||||
protected:
|
||||
virtual ~MobileConnectionListener() { }
|
||||
|
||||
private:
|
||||
uint32_t mClientId;
|
||||
};
|
||||
|
@ -59,10 +63,12 @@ public:
|
|||
NS_DECL_NSITELEPHONYLISTENER
|
||||
|
||||
TelephonyListener() { }
|
||||
virtual ~TelephonyListener() { }
|
||||
|
||||
bool Listen(bool aStart);
|
||||
|
||||
protected:
|
||||
virtual ~TelephonyListener() { }
|
||||
|
||||
private:
|
||||
nsresult HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend);
|
||||
};
|
||||
|
|
|
@ -179,6 +179,9 @@ public:
|
|||
BT_WARNING("Unable to get value for '" BLUETOOTH_ENABLED_SETTING "'");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
~StartupTask() { }
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(BluetoothService::StartupTask, nsISettingsServiceCallback);
|
||||
|
|
|
@ -35,7 +35,6 @@ public:
|
|||
static BluetoothA2dpManager* Get();
|
||||
static void InitA2dpInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitA2dpInterface(BluetoothProfileResultHandler* aRes);
|
||||
virtual ~BluetoothA2dpManager();
|
||||
|
||||
void OnConnectError();
|
||||
void OnDisconnectError();
|
||||
|
@ -65,6 +64,9 @@ public:
|
|||
void GetTitle(nsAString& aTitle);
|
||||
void GetArtist(nsAString& aArtist);
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothA2dpManager();
|
||||
|
||||
private:
|
||||
BluetoothA2dpManager();
|
||||
void ResetA2dp();
|
||||
|
|
|
@ -16,12 +16,13 @@ class BluetoothSetupResultHandler
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothSetupResultHandler)
|
||||
|
||||
virtual ~BluetoothSetupResultHandler();
|
||||
|
||||
virtual void OnError(BluetoothStatus aStatus);
|
||||
virtual void RegisterModule();
|
||||
virtual void UnregisterModule();
|
||||
virtual void Configuration();
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothSetupResultHandler();
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -43,7 +43,6 @@ public:
|
|||
|
||||
static const int MAX_PACKET_LENGTH = 0xFFFE;
|
||||
|
||||
virtual ~BluetoothOppManager();
|
||||
static BluetoothOppManager* Get();
|
||||
void ClientDataHandler(mozilla::ipc::UnixSocketRawData* aMessage);
|
||||
void ServerDataHandler(mozilla::ipc::UnixSocketRawData* aMessage);
|
||||
|
@ -73,6 +72,9 @@ public:
|
|||
virtual void OnSocketConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
virtual void OnSocketDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothOppManager();
|
||||
|
||||
private:
|
||||
BluetoothOppManager();
|
||||
bool Init();
|
||||
|
|
|
@ -1593,6 +1593,13 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
|
|||
}
|
||||
default:
|
||||
BT_WARNING("Got an unhandled status of BondStateChangedCallback!");
|
||||
// Dispatch a reply to unblock the waiting status of pairing.
|
||||
if (!sBondingRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sBondingRunnableArray[0],
|
||||
BluetoothValue(true),
|
||||
NS_LITERAL_STRING("Internal failure"));
|
||||
sBondingRunnableArray.RemoveElementAt(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,13 +29,15 @@ public:
|
|||
}
|
||||
|
||||
static BluetoothHfpManager* Get();
|
||||
virtual ~BluetoothHfpManager() { }
|
||||
static void InitHfpInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitHfpInterface(BluetoothProfileResultHandler* aRes);
|
||||
|
||||
bool ConnectSco();
|
||||
bool DisconnectSco();
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothHfpManager() { }
|
||||
|
||||
private:
|
||||
BluetoothHfpManager() { }
|
||||
bool Init();
|
||||
|
|
|
@ -73,7 +73,8 @@ IsSupportedChld(const int aChld) {
|
|||
return (aChld >= 0 && aChld <= 3);
|
||||
}
|
||||
|
||||
class BluetoothHfpManager::GetVolumeTask MOZ_FINAL : public nsISettingsServiceCallback
|
||||
class BluetoothHfpManager::GetVolumeTask MOZ_FINAL
|
||||
: public nsISettingsServiceCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -103,6 +104,9 @@ public:
|
|||
BT_WARNING("Unable to get value for '" AUDIO_VOLUME_BT_SCO_ID "'");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
~GetVolumeTask() { }
|
||||
};
|
||||
|
||||
class BluetoothHfpManager::CloseScoTask : public Task
|
||||
|
|
|
@ -88,7 +88,6 @@ public:
|
|||
}
|
||||
|
||||
static BluetoothHfpManager* Get();
|
||||
virtual ~BluetoothHfpManager();
|
||||
static void InitHfpInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitHfpInterface(BluetoothProfileResultHandler* aRes);
|
||||
|
||||
|
@ -138,6 +137,9 @@ public:
|
|||
const nsAString& aBdAddress) MOZ_OVERRIDE;
|
||||
void KeyPressedNotification(const nsAString& aBdAddress) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothHfpManager();
|
||||
|
||||
private:
|
||||
class GetVolumeTask;
|
||||
class CloseScoTask;
|
||||
|
|
|
@ -31,7 +31,6 @@ public:
|
|||
};
|
||||
|
||||
static BluetoothA2dpManager* Get();
|
||||
virtual ~BluetoothA2dpManager();
|
||||
|
||||
// A2DP-specific functions
|
||||
void HandleSinkPropertyChanged(const BluetoothSignal& aSignal);
|
||||
|
@ -55,6 +54,9 @@ public:
|
|||
uint64_t GetMediaNumber();
|
||||
void GetTitle(nsAString& aTitle);
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothA2dpManager();
|
||||
|
||||
private:
|
||||
BluetoothA2dpManager();
|
||||
bool Init();
|
||||
|
|
|
@ -196,6 +196,9 @@ public:
|
|||
BT_WARNING("Unable to get value for '" AUDIO_VOLUME_BT_SCO_ID "'");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
~GetVolumeTask() { }
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(BluetoothHfpManager::GetVolumeTask,
|
||||
|
|
|
@ -86,7 +86,6 @@ public:
|
|||
}
|
||||
|
||||
static BluetoothHfpManager* Get();
|
||||
~BluetoothHfpManager();
|
||||
|
||||
// The following functions are inherited from BluetoothSocketObserver
|
||||
virtual void ReceiveSocketData(
|
||||
|
@ -131,6 +130,9 @@ public:
|
|||
void ToggleCalls();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
~BluetoothHfpManager();
|
||||
|
||||
private:
|
||||
void ParseAtCommand(const nsACString& aAtCommand, const int aStart,
|
||||
nsTArray<nsCString>& aRetValues);
|
||||
|
|
|
@ -43,7 +43,6 @@ public:
|
|||
|
||||
static const int MAX_PACKET_LENGTH = 0xFFFE;
|
||||
|
||||
virtual ~BluetoothOppManager();
|
||||
static BluetoothOppManager* Get();
|
||||
void ClientDataHandler(mozilla::ipc::UnixSocketRawData* aMessage);
|
||||
void ServerDataHandler(mozilla::ipc::UnixSocketRawData* aMessage);
|
||||
|
@ -73,6 +72,9 @@ public:
|
|||
virtual void OnSocketConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
virtual void OnSocketDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothOppManager();
|
||||
|
||||
private:
|
||||
BluetoothOppManager();
|
||||
bool Init();
|
||||
|
|
|
@ -45,6 +45,10 @@ CameraPreferences::UpdatePref(const char* aPref, nsresult& aVal)
|
|||
nsresult rv = Preferences::GetUint(aPref, &val);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVal = static_cast<nsresult>(val);
|
||||
} else if(rv == NS_ERROR_UNEXPECTED) {
|
||||
// Preference does not exist
|
||||
rv = NS_OK;
|
||||
aVal = NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -57,6 +61,10 @@ CameraPreferences::UpdatePref(const char* aPref, uint32_t& aVal)
|
|||
nsresult rv = Preferences::GetUint(aPref, &val);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVal = val;
|
||||
} else if(rv == NS_ERROR_UNEXPECTED) {
|
||||
// Preference does not exist
|
||||
rv = NS_OK;
|
||||
aVal = 0;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -69,6 +77,10 @@ CameraPreferences::UpdatePref(const char* aPref, nsACString& aVal)
|
|||
nsresult rv = Preferences::GetCString(aPref, &val);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVal = val;
|
||||
} else if(rv == NS_ERROR_UNEXPECTED) {
|
||||
// Preference does not exist
|
||||
rv = NS_OK;
|
||||
aVal.Truncate();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -81,6 +93,10 @@ CameraPreferences::UpdatePref(const char* aPref, bool& aVal)
|
|||
nsresult rv = Preferences::GetBool(aPref, &val);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVal = val;
|
||||
} else if(rv == NS_ERROR_UNEXPECTED) {
|
||||
// Preference does not exist
|
||||
rv = NS_OK;
|
||||
aVal = false;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
|
||||
const MOZ_CAMERATESTHW_CONTRACTID = "@mozilla.org/cameratesthardware;1";
|
||||
const MOZ_CAMERATESTHW_CID = Components.ID("{fcb7b4cd-689e-453c-8a2c-611a45fa09ac}");
|
||||
const DEBUG = false;
|
||||
|
||||
function debug(msg) {
|
||||
if (DEBUG) {
|
||||
dump('-*- MozCameraTestHardware: ' + msg + '\n');
|
||||
}
|
||||
}
|
||||
|
||||
function MozCameraTestHardware() {
|
||||
this._params = {};
|
||||
}
|
||||
|
||||
MozCameraTestHardware.prototype = {
|
||||
classID: MOZ_CAMERATESTHW_CID,
|
||||
contractID: MOZ_CAMERATESTHW_CONTRACTID,
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({classID: MOZ_CAMERATESTHW_CID,
|
||||
contractID: MOZ_CAMERATESTHW_CONTRACTID,
|
||||
flags: Ci.nsIClassInfo.SINGLETON,
|
||||
interfaces: [Ci.nsICameraTestHardware]}),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICameraTestHardware]),
|
||||
|
||||
_params: null,
|
||||
_window: null,
|
||||
_mock: null,
|
||||
_handler: null,
|
||||
|
||||
attach: function(mock) {
|
||||
/* Waive xrays permits us to call functions provided to us
|
||||
in the mock */
|
||||
this._mock = Components.utils.waiveXrays(mock);
|
||||
},
|
||||
|
||||
detach: function() {
|
||||
this._mock = null;
|
||||
},
|
||||
|
||||
/* Trigger a delegate handler attached to the test hardware
|
||||
if given via attach. If there is no delegate attached, or
|
||||
it does not provide a handler for this specific operation,
|
||||
or the handler returns true, it will execute the default
|
||||
behaviour. The handler may throw an exception in order to
|
||||
return an error code from the driver call. */
|
||||
_delegate: function(prop) {
|
||||
return (this._mock && this._mock[prop] && !this._mock[prop]());
|
||||
},
|
||||
|
||||
get params() {
|
||||
return this._params;
|
||||
},
|
||||
|
||||
set params(aParams) {
|
||||
this._params = aParams;
|
||||
},
|
||||
|
||||
setHandler: function(handler) {
|
||||
this._handler = handler;
|
||||
},
|
||||
|
||||
dispatchEvent: function(evt) {
|
||||
if (this._handler) {
|
||||
this._handler.handleEvent(evt);
|
||||
}
|
||||
},
|
||||
|
||||
reset: function(aWindow) {
|
||||
this._window = aWindow;
|
||||
this._mock = null;
|
||||
this._params = {};
|
||||
},
|
||||
|
||||
initCamera: function() {
|
||||
this._delegate('init');
|
||||
},
|
||||
|
||||
pushParameters: function(params) {
|
||||
let oldParams = this._params;
|
||||
this._params = {};
|
||||
let s = params.split(';');
|
||||
for(let i = 0; i < s.length; ++i) {
|
||||
let parts = s[i].split('=');
|
||||
if (parts.length == 2) {
|
||||
this._params[parts[0]] = parts[1];
|
||||
}
|
||||
}
|
||||
try {
|
||||
this._delegate('pushParameters');
|
||||
} catch(e) {
|
||||
this._params = oldParams;
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
|
||||
pullParameters: function() {
|
||||
this._delegate('pullParameters');
|
||||
let ret = "";
|
||||
for(let p in this._params) {
|
||||
ret += p + "=" + this._params[p] + ";";
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
autoFocus: function() {
|
||||
if (!this._delegate('autoFocus')) {
|
||||
this.fireAutoFocusComplete(true);
|
||||
}
|
||||
},
|
||||
|
||||
fireAutoFocusMoving: function(moving) {
|
||||
let evt = new this._window.CameraStateChangeEvent('focus', { 'newState': moving ? 'focusing' : 'not_focusing' } );
|
||||
this.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
fireAutoFocusComplete: function(state) {
|
||||
let evt = new this._window.CameraStateChangeEvent('focus', { 'newState': state ? 'focused' : 'unfocused' } );
|
||||
this.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
cancelAutoFocus: function() {
|
||||
this._delegate('cancelAutoFocus');
|
||||
},
|
||||
|
||||
fireShutter: function() {
|
||||
let evt = new this._window.Event('shutter');
|
||||
this.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
takePicture: function() {
|
||||
if (!this._delegate('takePicture')) {
|
||||
this.fireTakePictureComplete(new this._window.Blob(['foobar'], {'type': 'jpeg'}));
|
||||
}
|
||||
},
|
||||
|
||||
fireTakePictureComplete: function(blob) {
|
||||
let evt = new this._window.BlobEvent('picture', {'data': blob});
|
||||
this.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
fireTakePictureError: function() {
|
||||
let evt = new this._window.ErrorEvent('error', {'message': 'picture'});
|
||||
this.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
cancelTakePicture: function() {
|
||||
this._delegate('cancelTakePicture');
|
||||
},
|
||||
|
||||
startPreview: function() {
|
||||
this._delegate('startPreview');
|
||||
},
|
||||
|
||||
stopPreview: function() {
|
||||
this._delegate('stopPreview');
|
||||
},
|
||||
|
||||
startFaceDetection: function() {
|
||||
this._delegate('startFaceDetection');
|
||||
},
|
||||
|
||||
stopFaceDetection: function() {
|
||||
this._delegate('stopFaceDetection');
|
||||
},
|
||||
|
||||
fireFacesDetected: function(faces) {
|
||||
/* This works around the fact that we can't have references to
|
||||
dictionaries in a dictionary in WebIDL; we provide a boolean
|
||||
to indicate whether or not the values for those features are
|
||||
actually valid. */
|
||||
let facesIf = [];
|
||||
if (typeof(faces) === 'object' && typeof(faces.faces) === 'object') {
|
||||
let self = this;
|
||||
faces.faces.forEach(function(face) {
|
||||
face.hasLeftEye = face.hasOwnProperty('leftEye') && face.leftEye != null;
|
||||
face.hasRightEye = face.hasOwnProperty('rightEye') && face.rightEye != null;
|
||||
face.hasMouth = face.hasOwnProperty('mouth') && face.mouth != null;
|
||||
facesIf.push(new self._window.CameraDetectedFace(face));
|
||||
});
|
||||
}
|
||||
|
||||
let evt = new this._window.CameraFacesDetectedEvent('facesdetected', {'faces': facesIf});
|
||||
this.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
startRecording: function() {
|
||||
this._delegate('startRecording');
|
||||
},
|
||||
|
||||
stopRecording: function() {
|
||||
this._delegate('stopRecording');
|
||||
},
|
||||
|
||||
fireSystemError: function() {
|
||||
let evt = new this._window.ErrorEvent('error', {'message': 'system'});
|
||||
this.dispatchEvent(evt);
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozCameraTestHardware]);
|
|
@ -0,0 +1,2 @@
|
|||
component {fcb7b4cd-689e-453c-8a2c-611a45fa09ac} CameraTestHardware.js
|
||||
contract @mozilla.org/cameratesthardware;1 {fcb7b4cd-689e-453c-8a2c-611a45fa09ac}
|
|
@ -31,6 +31,40 @@ DOMCameraDetectedFace::WrapObject(JSContext* aCx)
|
|||
return CameraDetectedFaceBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<DOMCameraDetectedFace>
|
||||
DOMCameraDetectedFace::Constructor(const GlobalObject& aGlobal,
|
||||
const dom::CameraDetectedFaceInit& aFace,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<DOMCameraDetectedFace> face =
|
||||
new DOMCameraDetectedFace(aGlobal.GetAsSupports(), aFace);
|
||||
return face.forget();
|
||||
}
|
||||
|
||||
DOMCameraDetectedFace::DOMCameraDetectedFace(nsISupports* aParent,
|
||||
const dom::CameraDetectedFaceInit& aFace)
|
||||
: mParent(aParent)
|
||||
, mId(aFace.mId)
|
||||
, mScore(aFace.mScore)
|
||||
, mBounds(new DOMRect(this))
|
||||
{
|
||||
mBounds->SetRect(aFace.mBounds.mLeft,
|
||||
aFace.mBounds.mTop,
|
||||
aFace.mBounds.mRight - aFace.mBounds.mLeft,
|
||||
aFace.mBounds.mBottom - aFace.mBounds.mTop);
|
||||
|
||||
if (aFace.mHasLeftEye) {
|
||||
mLeftEye = new DOMPoint(this, aFace.mLeftEye.mX, aFace.mLeftEye.mY);
|
||||
}
|
||||
if (aFace.mHasRightEye) {
|
||||
mRightEye = new DOMPoint(this, aFace.mRightEye.mX, aFace.mRightEye.mY);
|
||||
}
|
||||
if (aFace.mHasMouth) {
|
||||
mMouth = new DOMPoint(this, aFace.mMouth.mX, aFace.mMouth.mY);
|
||||
}
|
||||
}
|
||||
|
||||
DOMCameraDetectedFace::DOMCameraDetectedFace(nsISupports* aParent,
|
||||
const ICameraControl::Face& aFace)
|
||||
: mParent(aParent)
|
||||
|
|
|
@ -30,6 +30,10 @@ public:
|
|||
// Great Renaming proposed in bug 983177.
|
||||
static bool HasSupport(JSContext* aCx, JSObject* aGlobal);
|
||||
|
||||
static already_AddRefed<DOMCameraDetectedFace> Constructor(const GlobalObject& aGlobal,
|
||||
const dom::CameraDetectedFaceInit& aFace,
|
||||
ErrorResult& aRv);
|
||||
|
||||
DOMCameraDetectedFace(nsISupports* aParent, const ICameraControl::Face& aFace);
|
||||
|
||||
uint32_t Id() { return mId; }
|
||||
|
@ -54,6 +58,7 @@ public:
|
|||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
DOMCameraDetectedFace(nsISupports* aParent, const dom::CameraDetectedFaceInit& aFace);
|
||||
virtual ~DOMCameraDetectedFace() { }
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "nsDOMClassInfo.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/CameraManagerBinding.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2014 Mozilla Foundation
|
||||
* Copyright (C) 2012-2015 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -221,18 +221,23 @@ GonkCameraHardware::Init()
|
|||
sp<GonkCameraHardware>
|
||||
GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId)
|
||||
{
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
|
||||
sp<Camera> camera = Camera::connect(aCameraId, /* clientPackageName */String16("gonk.camera"), Camera::USE_CALLING_UID);
|
||||
#else
|
||||
sp<Camera> camera = Camera::connect(aCameraId);
|
||||
#endif
|
||||
|
||||
if (camera.get() == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
sp<Camera> camera;
|
||||
|
||||
nsCString test;
|
||||
CameraPreferences::GetPref("camera.control.test.enabled", test);
|
||||
|
||||
if (!test.EqualsASCII("hardware")) {
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
|
||||
camera = Camera::connect(aCameraId, /* clientPackageName */String16("gonk.camera"), Camera::USE_CALLING_UID);
|
||||
#else
|
||||
camera = Camera::connect(aCameraId);
|
||||
#endif
|
||||
|
||||
if (camera.get() == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
sp<GonkCameraHardware> cameraHardware;
|
||||
if (test.EqualsASCII("hardware")) {
|
||||
NS_WARNING("Using test Gonk hardware layer");
|
||||
|
@ -257,8 +262,10 @@ GonkCameraHardware::Close()
|
|||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, (void*)this);
|
||||
|
||||
mClosing = true;
|
||||
mCamera->stopPreview();
|
||||
mCamera->disconnect();
|
||||
if (mCamera.get()) {
|
||||
mCamera->stopPreview();
|
||||
mCamera->disconnect();
|
||||
}
|
||||
if (mNativeWindow.get()) {
|
||||
mNativeWindow->abandon();
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2014 Mozilla Foundation
|
||||
* Copyright (C) 2013-2015 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,59 +18,55 @@
|
|||
#define DOM_CAMERA_TESTGONKCAMERAHARDWARE_H
|
||||
|
||||
#include "GonkCameraHwMgr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
|
||||
namespace android {
|
||||
namespace mozilla {
|
||||
|
||||
class TestGonkCameraHardware : public android::GonkCameraHardware
|
||||
{
|
||||
public:
|
||||
virtual nsresult Init() MOZ_OVERRIDE;
|
||||
virtual int AutoFocus() MOZ_OVERRIDE;
|
||||
virtual int StartFaceDetection() MOZ_OVERRIDE;
|
||||
virtual int StopFaceDetection() MOZ_OVERRIDE;
|
||||
virtual int TakePicture() MOZ_OVERRIDE;
|
||||
virtual void CancelTakePicture() MOZ_OVERRIDE;
|
||||
virtual int StartPreview() MOZ_OVERRIDE;
|
||||
virtual void StopPreview() MOZ_OVERRIDE;
|
||||
virtual int PushParameters(const mozilla::GonkCameraParameters& aParams) MOZ_OVERRIDE;
|
||||
virtual nsresult PullParameters(mozilla::GonkCameraParameters& aParams) MOZ_OVERRIDE;
|
||||
virtual int StartRecording() MOZ_OVERRIDE;
|
||||
virtual int StopRecording() MOZ_OVERRIDE;
|
||||
virtual int SetListener(const sp<GonkCameraListener>& aListener) MOZ_OVERRIDE;
|
||||
virtual int StoreMetaDataInBuffers(bool aEnabled) MOZ_OVERRIDE;
|
||||
|
||||
virtual int
|
||||
PushParameters(const CameraParameters& aParams) MOZ_OVERRIDE
|
||||
{
|
||||
return GonkCameraHardware::PushParameters(aParams);
|
||||
}
|
||||
|
||||
virtual void
|
||||
PullParameters(CameraParameters& aParams) MOZ_OVERRIDE
|
||||
{
|
||||
GonkCameraHardware::PullParameters(aParams);
|
||||
}
|
||||
virtual int PushParameters(const android::CameraParameters& aParams) MOZ_OVERRIDE;
|
||||
virtual void PullParameters(android::CameraParameters& aParams) MOZ_OVERRIDE;
|
||||
|
||||
TestGonkCameraHardware(mozilla::nsGonkCameraControl* aTarget,
|
||||
uint32_t aCameraId,
|
||||
const sp<Camera>& aCamera);
|
||||
virtual ~TestGonkCameraHardware();
|
||||
|
||||
virtual nsresult Init() MOZ_OVERRIDE;
|
||||
const android::sp<android::Camera>& aCamera);
|
||||
|
||||
protected:
|
||||
const nsCString TestCase();
|
||||
const nsCString GetExtraParameters();
|
||||
bool IsTestCaseInternal(const char* aTest, const char* aFile, int aLine);
|
||||
int TestCaseError(int aDefaultError);
|
||||
virtual ~TestGonkCameraHardware();
|
||||
|
||||
int StartAutoFocusMoving(bool aIsMoving);
|
||||
void InjectFakeSystemFailure();
|
||||
class ControlMessage;
|
||||
class PushParametersDelegate;
|
||||
class PullParametersDelegate;
|
||||
|
||||
nsresult WaitWhileRunningOnMainThread(nsRefPtr<ControlMessage> aRunnable);
|
||||
|
||||
nsCOMPtr<nsIDOMEventListener> mDomListener;
|
||||
nsCOMPtr<nsIThread> mCameraThread;
|
||||
mozilla::Mutex mMutex;
|
||||
mozilla::CondVar mCondVar;
|
||||
nsresult mStatus;
|
||||
|
||||
private:
|
||||
TestGonkCameraHardware(const TestGonkCameraHardware&) = delete;
|
||||
TestGonkCameraHardware& operator=(const TestGonkCameraHardware&) = delete;
|
||||
};
|
||||
|
||||
#define IsTestCase(test) IsTestCaseInternal((test), __FILE__, __LINE__)
|
||||
|
||||
} // namespace android
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // DOM_CAMERA_TESTGONKCAMERAHARDWARE_H
|
||||
|
|
|
@ -25,6 +25,12 @@ UNIFIED_SOURCES += [
|
|||
]
|
||||
|
||||
if CONFIG['MOZ_B2G_CAMERA']:
|
||||
XPIDL_SOURCES += [
|
||||
'nsICameraTestHardware.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_camera'
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'GonkCameraControl.cpp',
|
||||
'GonkCameraHwMgr.cpp',
|
||||
|
@ -36,6 +42,11 @@ if CONFIG['MOZ_B2G_CAMERA']:
|
|||
'TestGonkCameraControl.cpp',
|
||||
'TestGonkCameraHardware.cpp',
|
||||
]
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'CameraTestHardware.js',
|
||||
'CameraTestHardware.manifest',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'FallbackCameraControl.cpp',
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMBlob;
|
||||
interface nsIDOMEventListener;
|
||||
|
||||
[scriptable, uuid(2e567730-f164-49d7-b975-862caa4425a5)]
|
||||
interface nsICameraTestHardware : nsISupports
|
||||
{
|
||||
/* The following methods are intended to be used by the test cases
|
||||
written in JavaScript to define the behaviour of the hardware: */
|
||||
|
||||
/* Attach a delegate handler object such that the test hardware
|
||||
will call the given handlers for the given operations to decide
|
||||
what to do. This allows a test case to define specific behaviours
|
||||
on a fine grained basis.
|
||||
|
||||
The following handlers may be supplied as properties of the
|
||||
given delagate handler object:
|
||||
autoFocus
|
||||
cancelAutoFocus
|
||||
cancelTakePicture
|
||||
init
|
||||
pushParameters
|
||||
pullParameters
|
||||
startFaceDetection
|
||||
startPreview
|
||||
startRecording
|
||||
stopFaceDetection
|
||||
stopPreview
|
||||
stopRecording
|
||||
takePicture
|
||||
|
||||
Implementation notes for handlers:
|
||||
|
||||
- If the handler throws an error, we will the return code
|
||||
of the driver operation.
|
||||
|
||||
- If the handler returns true, we will perform the default
|
||||
action (if any) for the operation. */
|
||||
void attach(in jsval mock);
|
||||
|
||||
/* Detach a delegate handler object such that the test hardware
|
||||
will revert to default behaviour when a function is called. */
|
||||
void detach();
|
||||
|
||||
/* Reset the state of the test hardware back to the initial state.
|
||||
This is useful when one test case has been completed and we need
|
||||
a clean slate for the next. */
|
||||
void reset(in jsval window);
|
||||
|
||||
/* Trigger an OnAutoFocusMoving callback at the Gonk layer.
|
||||
|
||||
state is a boolean indicating where or not the camera focus
|
||||
is moving. */
|
||||
void fireAutoFocusComplete(in boolean state);
|
||||
|
||||
/* Trigger an OnAutoFocusComplete callback at the Gonk layer.
|
||||
|
||||
state is a boolean indicating where or not the camera is focused. */
|
||||
void fireAutoFocusMoving(in boolean moving);
|
||||
|
||||
/* Trigger an OnTakePictureComplete callback at the Gonk layer.
|
||||
|
||||
blob should be a Blob object. The actual content of the blob
|
||||
is unimportant since nothing processes it as an image internally. */
|
||||
void fireTakePictureComplete(in nsIDOMBlob picture);
|
||||
|
||||
/* Trigger an OnTakePictureError callback at the Gonk layer. */
|
||||
void fireTakePictureError();
|
||||
|
||||
/* Trigger an OnSystemError callback at the Gonk layer. */
|
||||
void fireSystemError();
|
||||
|
||||
/* Trigger an OnShutter callback at the Gonk layer. */
|
||||
void fireShutter();
|
||||
|
||||
/* Trigger an OnFacesDetected callback at the Gonk layer.
|
||||
|
||||
faces is an array of CameraDetectedFaceInit dictionaries although
|
||||
hasLeftEye, hasRightEye and hasMouth may be omitted and will be
|
||||
implied by the presence/absence of leftEye, rightEye and mouth. */
|
||||
void fireFacesDetected(in jsval faces);
|
||||
|
||||
/* Object which stores the camera parameters read/written by the
|
||||
camera control layer from the hardware. The test case may set
|
||||
its own values to control the behaviour of the camera middleware.
|
||||
|
||||
E.g. params['preview-sizes'] = '320x240,640x480'; */
|
||||
attribute jsval params;
|
||||
|
||||
/* The following methods are intended to be used by the Gonk layer
|
||||
in order to call back into JavaScript to get test case defined
|
||||
behaviour: */
|
||||
|
||||
/* Set a handler to capture asynchronous events triggered by the
|
||||
test case via the fireXXX methods. E.g.:
|
||||
|
||||
nsCOMPtr<nsICameraHardware> wrapper =
|
||||
do_GetService("@mozilla.org/cameratesthardware;1");
|
||||
|
||||
nsCOMPtr<nsIDOMEventListener> listener = new HwListener();
|
||||
|
||||
wrapper->setHander(listener);
|
||||
|
||||
where
|
||||
|
||||
class HwListener : public nsIDOMEventListener {
|
||||
NS_IMETHODIMP HandleEvent(nsIDOMEvent *aEvent) {
|
||||
nsString type;
|
||||
aEvent->GetType(&type);
|
||||
if (aEvent.EqualsLiteral("focus")) {
|
||||
...
|
||||
} else {
|
||||
...
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
The following event types may be generated:
|
||||
focus: CameraStateChangeEvent where newState should map
|
||||
to the OnAutoFocusComplete and OnAutoFocusMoving callbacks:
|
||||
-- focused: OnAutoFocusComplete(false)
|
||||
-- unfocused: OnAutoFocusComplete(true)
|
||||
-- focusing: OnAutoFocusMoving(true)
|
||||
-- not_focusing: OnAutoFocusMoving(false)
|
||||
|
||||
picture: BlobEvent which contains the picture type and
|
||||
data corresponding to the OnTakePictureComplete callback.
|
||||
|
||||
error: ErrorEvent corresponding to the various error callbacks,
|
||||
where the message is:
|
||||
-- picture: OnTakePictureError()
|
||||
-- system: OnSystemError(100, 0)
|
||||
|
||||
facesdetected: CameraFacesDetectedEvent which contains the
|
||||
faces data corresponding to OnFacesDetected callback.
|
||||
|
||||
shutter: Event which corresponds to the OnShutter callback. */
|
||||
void setHandler(in nsIDOMEventListener handler);
|
||||
|
||||
/* Execute an intercepted Init() driver call. */
|
||||
void initCamera();
|
||||
|
||||
/* Execute an intercepted AutoFocus() driver call. Default behaviour is
|
||||
to trigger OnAutoFocusComplete where the camera is focused. */
|
||||
void autoFocus();
|
||||
|
||||
/* Execute an intercepted CancelAutoFocus() driver call. */
|
||||
void cancelAutoFocus();
|
||||
|
||||
/* Execute an intercepted StartFaceDetection() driver call. */
|
||||
void startFaceDetection();
|
||||
|
||||
/* Execute an intercepted StopFaceDetection() driver call. */
|
||||
void stopFaceDetection();
|
||||
|
||||
/* Execute an intercepted TakePicture() driver call. Default behaviour is
|
||||
to trigger OnTakePictureComplete with a fake jpeg blob. */
|
||||
void takePicture();
|
||||
|
||||
/* Execute an intercepted CancelTakePicture() driver call. */
|
||||
void cancelTakePicture();
|
||||
|
||||
/* Execute an intercepted StartPreview() driver call. */
|
||||
void startPreview();
|
||||
|
||||
/* Execute an intercepted StopPreview() driver call. */
|
||||
void stopPreview();
|
||||
|
||||
/* Execute an intercepted StartRecording() driver call. */
|
||||
void startRecording();
|
||||
|
||||
/* Execute an intercepted StopRecording() driver call. */
|
||||
void stopRecording();
|
||||
|
||||
/* Execute an intercepted PushParameters() driver call. If the delegate
|
||||
handler throws an error, it will restore the old parameters.
|
||||
When the delegate is called, the new proposed parameters are
|
||||
placed in this.params. */
|
||||
void pushParameters(in DOMString params);
|
||||
|
||||
/* Execute an intercepted PullParameters() driver call. Unless the delegate
|
||||
handler throws an error, it will return an assembled parameter
|
||||
list derived from the this.params hash table. */
|
||||
DOMString pullParameters();
|
||||
};
|
||||
|
|
@ -1,169 +1,396 @@
|
|||
var CameraTest = (function() {
|
||||
'use strict';
|
||||
function isDefinedObj(obj) {
|
||||
return typeof(obj) !== 'undefined' && obj != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 'camera.control.test.enabled' is queried in Gecko to enable different
|
||||
* test modes in the camera stack. The only currently-supported setting
|
||||
* is 'hardware', which wraps the Gonk camera abstraction class in a
|
||||
* shim class that supports injecting hardware camera API failures into
|
||||
* the execution path.
|
||||
*
|
||||
* The affected API is specified by the 'camera.control.test.hardware'
|
||||
* pref. Currently supported values should be determined by inspecting
|
||||
* TestGonkCameraHardware.cpp.
|
||||
*
|
||||
* Some API calls are simple: e.g. 'start-recording-failure' will cause
|
||||
* the DOM-facing startRecording() call to fail. More complex tests like
|
||||
* 'take-picture-failure' will cause the takePicture() API to fail, while
|
||||
* 'take-picture-process-failure' will simulate a failure of the
|
||||
* asynchronous picture-taking process, even if the initial API call
|
||||
* path seems to have succeeded.
|
||||
*
|
||||
* If 'camera.control.test.hardware.gonk.parameters' is set, it will cause
|
||||
* the contents of that string to be appended to the string of parameters
|
||||
* pulled from the Gonk camera library. This allows tests to inject fake
|
||||
* settings/capabilities for features not supported by the emulator. These
|
||||
* parameters are one or more semicolon-delimited key=value pairs, e.g. to
|
||||
* pretend the emulator supports zoom:
|
||||
*
|
||||
* zoom-ratios=100,150,200,300,400;max-zoom=4
|
||||
*
|
||||
* This means (of course) that neither the key not the value tokens can
|
||||
* contain either equals signs or semicolons. The test shim doesn't enforce
|
||||
* this so that we can test getting junk from the camera library as well.
|
||||
*/
|
||||
const PREF_TEST_ENABLED = "camera.control.test.enabled";
|
||||
const PREF_TEST_HARDWARE = "camera.control.test.hardware";
|
||||
const PREF_TEST_EXTRA_PARAMETERS = "camera.control.test.hardware.gonk.parameters";
|
||||
const PREF_TEST_FAKE_LOW_MEMORY = "camera.control.test.is_low_memory";
|
||||
var oldTestEnabled;
|
||||
var oldTestHw;
|
||||
var testMode;
|
||||
function isDefined(obj) {
|
||||
return typeof(obj) !== 'undefined';
|
||||
}
|
||||
|
||||
function testHardwareSetFakeParameters(parameters, callback) {
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_EXTRA_PARAMETERS, parameters]]}, function() {
|
||||
var setParams = SpecialPowers.getCharPref(PREF_TEST_EXTRA_PARAMETERS);
|
||||
ise(setParams, parameters, "Extra test parameters '" + setParams + "'");
|
||||
if (callback) {
|
||||
callback(setParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
/* This is a simple test suite class removing the need to
|
||||
write a lot of boilerplate for camera tests. It can
|
||||
manage the platform configurations for testing, any
|
||||
cleanup required, and common actions such as fetching
|
||||
the camera or waiting for the preview to be completed.
|
||||
|
||||
function testHardwareClearFakeParameters(callback) {
|
||||
SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_EXTRA_PARAMETERS]]}, callback);
|
||||
}
|
||||
To create the suite:
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
function testHardwareSetFakeLowMemoryPlatform(callback) {
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_FAKE_LOW_MEMORY, true]]}, function() {
|
||||
var setParams = SpecialPowers.getBoolPref(PREF_TEST_FAKE_LOW_MEMORY);
|
||||
ise(setParams, true, "Fake low memory platform");
|
||||
if (callback) {
|
||||
callback(setParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
To add a test case to the suite:
|
||||
suite.test('test-name', function() {
|
||||
function startAutoFocus(p) {
|
||||
return suite.camera.autoFocus();
|
||||
}
|
||||
|
||||
function testHardwareClearFakeLowMemoryPlatform(callback) {
|
||||
SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_FAKE_LOW_MEMORY]]}, callback);
|
||||
}
|
||||
return suite.getCamera()
|
||||
.then(startAutoFocus, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
function testHardwareSet(test, callback) {
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_HARDWARE, test]]}, function() {
|
||||
var setTest = SpecialPowers.getCharPref(PREF_TEST_HARDWARE);
|
||||
ise(setTest, test, "Test subtype set to " + setTest);
|
||||
if (callback) {
|
||||
callback(setTest);
|
||||
}
|
||||
});
|
||||
}
|
||||
Finally, to execute the test cases:
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
function testHardwareDone(callback) {
|
||||
testMode = null;
|
||||
if (oldTestHw) {
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_HARDWARE, oldTestHw]]}, callback);
|
||||
} else {
|
||||
SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_HARDWARE]]}, callback);
|
||||
Behind the scenes, suite configured the native camera
|
||||
to use the JS hardware, setup that hardware such that
|
||||
the getCamera would succeed, got a camera control
|
||||
reference and saved it to suite.camera, and after the
|
||||
tests were finished, it reset any modified state,
|
||||
released the camera object, and concluded the mochitest
|
||||
appropriately.
|
||||
*/
|
||||
function CameraTestSuite() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
this._window = window;
|
||||
this._document = document;
|
||||
this.viewfinder = document.getElementById('viewfinder');
|
||||
this._tests = [];
|
||||
this.hwType = '';
|
||||
|
||||
/* Ensure that the this pointer is bound to all functions so that
|
||||
they may be used as promise resolve/reject handlers without any
|
||||
special effort, permitting code like this:
|
||||
|
||||
getCamera().catch(suite.rejectGetCamera);
|
||||
|
||||
instead of:
|
||||
|
||||
getCamera().catch(suite.rejectGetCamera.bind(suite));
|
||||
*/
|
||||
this.setup = this._setup.bind(this);
|
||||
this.teardown = this._teardown.bind(this);
|
||||
this.test = this._test.bind(this);
|
||||
this.run = this._run.bind(this);
|
||||
this.waitPreviewStarted = this._waitPreviewStarted.bind(this);
|
||||
this.waitParameterPush = this._waitParameterPush.bind(this);
|
||||
this.initJsHw = this._initJsHw.bind(this);
|
||||
this.getCamera = this._getCamera.bind(this);
|
||||
this.setLowMemoryPlatform = this._setLowMemoryPlatform.bind(this);
|
||||
this.logError = this._logError.bind(this);
|
||||
this.expectedError = this._expectedError.bind(this);
|
||||
this.expectedRejectGetCamera = this._expectedRejectGetCamera.bind(this);
|
||||
this.expectedRejectAutoFocus = this._expectedRejectAutoFocus.bind(this);
|
||||
this.expectedRejectTakePicture = this._expectedRejectTakePicture.bind(this);
|
||||
this.rejectGetCamera = this._rejectGetCamera.bind(this);
|
||||
this.rejectRelease = this._rejectRelease.bind(this);
|
||||
this.rejectAutoFocus = this._rejectAutoFocus.bind(this);
|
||||
this.rejectTakePicture = this._rejectTakePicture.bind(this);
|
||||
this.rejectPreviewStarted = this._rejectPreviewStarted.bind(this);
|
||||
|
||||
var self = this;
|
||||
this._window.addEventListener('beforeunload', function() {
|
||||
if (isDefinedObj(self.viewfinder)) {
|
||||
self.viewfinder.mozSrcObject = null;
|
||||
}
|
||||
}
|
||||
|
||||
function testBegin(mode, callback) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
try {
|
||||
oldTestEnabled = SpecialPowers.getCharPref(PREF_TEST_ENABLED);
|
||||
} catch(e) { }
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_ENABLED, mode]]}, function() {
|
||||
var setMode = SpecialPowers.getCharPref(PREF_TEST_ENABLED);
|
||||
ise(setMode, mode, "Test mode set to " + setMode);
|
||||
if (setMode === "hardware") {
|
||||
self.hw = null;
|
||||
if (isDefinedObj(self.camera)) {
|
||||
ok(false, 'window unload triggered camera release instead of test completion');
|
||||
self.camera.release();
|
||||
self.camera = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CameraTestSuite.prototype = {
|
||||
camera: null,
|
||||
hw: null,
|
||||
_lowMemSet: false,
|
||||
|
||||
/* Returns a promise which is resolved when the test suite is ready
|
||||
to be executing individual test cases. One may provide the expected
|
||||
hardware type here if desired; the default is to use the JS test
|
||||
hardware. Use '' for the native emulated camera hardware. */
|
||||
_setup: function(hwType) {
|
||||
if (!isDefined(hwType)) {
|
||||
hwType = 'hardware';
|
||||
}
|
||||
|
||||
this._hwType = hwType;
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.pushPrefEnv({'set': [['camera.control.test.enabled', hwType]]}, function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/* Returns a promise which is resolved when all of the SpecialPowers
|
||||
parameters that were set while testing are flushed. This includes
|
||||
camera.control.test.enabled and camera.control.test.is_low_memory. */
|
||||
_teardown: function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.flushPrefEnv(function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/* Returns a promise which is resolved when the set low memory
|
||||
parameter is set. If no value is given, it defaults to true.
|
||||
This is intended to be used inside a test case at the beginning
|
||||
of its promise chain to configure the platform as desired. */
|
||||
_setLowMemoryPlatform: function(val) {
|
||||
if (typeof(val) === 'undefined') {
|
||||
val = true;
|
||||
}
|
||||
|
||||
if (this._lowMemSet === val) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.pushPrefEnv({'set': [['camera.control.test.is_low_memory', val]]}, function() {
|
||||
self._lowMemSet = val;
|
||||
resolve();
|
||||
});
|
||||
}).catch(function(e) {
|
||||
return self.logError('set low memory ' + val + ' failed', e);
|
||||
});
|
||||
},
|
||||
|
||||
/* Add a test case to the test suite to be executed later. */
|
||||
_test: function(aName, aCb) {
|
||||
this._tests.push({
|
||||
name: aName,
|
||||
cb: aCb
|
||||
});
|
||||
},
|
||||
|
||||
/* Execute all test cases (after setup is called). */
|
||||
_run: function() {
|
||||
var test = this._tests.shift();
|
||||
var self = this;
|
||||
if (test) {
|
||||
info(test.name + ' started');
|
||||
|
||||
function runNextTest() {
|
||||
self.run();
|
||||
}
|
||||
|
||||
function resetLowMem() {
|
||||
return self.setLowMemoryPlatform(false);
|
||||
}
|
||||
|
||||
function postTest(pass) {
|
||||
ok(pass, test.name + ' finished');
|
||||
var camera = self.camera;
|
||||
self.viewfinder.mozSrcObject = null;
|
||||
self.camera = null;
|
||||
|
||||
if (!isDefinedObj(camera)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function handler(e) {
|
||||
ok(typeof(e) === 'undefined', 'camera released');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return camera.release().then(handler).catch(handler);
|
||||
}
|
||||
|
||||
this.initJsHw();
|
||||
|
||||
var testPromise;
|
||||
try {
|
||||
testPromise = test.cb();
|
||||
if (!isDefinedObj(testPromise)) {
|
||||
testPromise = Promise.resolve();
|
||||
}
|
||||
} catch(e) {
|
||||
ok(false, 'caught exception while running test: ' + e);
|
||||
testPromise = Promise.reject(e);
|
||||
}
|
||||
|
||||
testPromise
|
||||
.then(function(p) {
|
||||
return postTest(true);
|
||||
}, function(e) {
|
||||
self.logError('unhandled error', e);
|
||||
return postTest(false);
|
||||
})
|
||||
.then(resetLowMem, resetLowMem)
|
||||
.then(runNextTest, runNextTest);
|
||||
} else {
|
||||
ok(true, 'all tests completed');
|
||||
var finish = SimpleTest.finish.bind(SimpleTest);
|
||||
this.teardown().then(finish, finish);
|
||||
}
|
||||
},
|
||||
|
||||
/* If the JS hardware is in use, get (and possibly initialize)
|
||||
the service XPCOM object. The native Gonk layers are able
|
||||
to get it via the same mechanism. Save a reference to it
|
||||
so that the test case may manipulate it as it sees fit in
|
||||
this.hw. Minimal setup is done for the test hardware such
|
||||
that the camera is able to be brought up without issue.
|
||||
|
||||
This function has no effect if the JS hardware is not used. */
|
||||
_initJsHw: function() {
|
||||
if (this._hwType === 'hardware') {
|
||||
this.hw = SpecialPowers.Cc['@mozilla.org/cameratesthardware;1']
|
||||
.getService(SpecialPowers.Ci.nsICameraTestHardware);
|
||||
this.hw.reset(this._window);
|
||||
|
||||
/* Minimum parameters required to get camera started */
|
||||
this.hw.params['preview-size'] = '320x240';
|
||||
this.hw.params['preview-size-values'] = '320x240';
|
||||
this.hw.params['picture-size-values'] = '320x240';
|
||||
} else {
|
||||
this.hw = null;
|
||||
}
|
||||
},
|
||||
|
||||
/* Returns a promise which resolves when the camera has
|
||||
been successfully opened with the given name and
|
||||
configuration. If no name is given, it uses the first
|
||||
camera in the list from the camera manager. */
|
||||
_getCamera: function(name, config) {
|
||||
var cameraManager = navigator.mozCameras;
|
||||
if (!isDefined(name)) {
|
||||
name = cameraManager.getListOfCameras()[0];
|
||||
}
|
||||
|
||||
var self = this;
|
||||
return cameraManager.getCamera(name, config).then(
|
||||
function(p) {
|
||||
ok(isDefinedObj(p) && isDefinedObj(p.camera), 'got camera');
|
||||
self.camera = p.camera;
|
||||
/* Ensure a followup promise can verify config by
|
||||
returning the same parameter again. */
|
||||
return Promise.resolve(p);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/* Returns a promise which resolves when the camera has
|
||||
successfully started the preview and is bound to the
|
||||
given viewfinder object. Note that this requires that
|
||||
a video element be present with the ID 'viewfinder'. */
|
||||
_waitPreviewStarted: function() {
|
||||
var self = this;
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
function onPreviewStateChange(e) {
|
||||
try {
|
||||
oldTestHw = SpecialPowers.getCharPref(PREF_TEST_HARDWARE);
|
||||
} catch(e) { }
|
||||
testMode = {
|
||||
set: testHardwareSet,
|
||||
setFakeParameters: testHardwareSetFakeParameters,
|
||||
clearFakeParameters: testHardwareClearFakeParameters,
|
||||
setFakeLowMemoryPlatform: testHardwareSetFakeLowMemoryPlatform,
|
||||
clearFakeLowMemoryPlatform: testHardwareClearFakeLowMemoryPlatform,
|
||||
done: testHardwareDone
|
||||
};
|
||||
if (callback) {
|
||||
callback(testMode);
|
||||
if (e.newState === 'started') {
|
||||
ok(true, 'viewfinder is ready and playing');
|
||||
self.camera.removeEventListener('previewstatechange', onPreviewStateChange);
|
||||
resolve();
|
||||
}
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDefinedObj(self.viewfinder)) {
|
||||
reject(new Error('no viewfinder object'));
|
||||
return;
|
||||
}
|
||||
|
||||
self.viewfinder.mozSrcObject = self.camera;
|
||||
self.viewfinder.play();
|
||||
self.camera.addEventListener('previewstatechange', onPreviewStateChange);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
function testEnd(callback) {
|
||||
// A chain of clean-up functions....
|
||||
function allCleanedUp() {
|
||||
SimpleTest.finish();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
/* Returns a promise which resolves when the camera hardware
|
||||
has received a push parameters request. This is useful
|
||||
when setting camera parameters from the application and
|
||||
you want confirmation when the operation is complete if
|
||||
there is no asynchronous notification provided. */
|
||||
_waitParameterPush: function() {
|
||||
var self = this;
|
||||
|
||||
function cleanUpTestEnabled() {
|
||||
var next = allCleanedUp;
|
||||
if (oldTestEnabled) {
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_ENABLED, oldTestEnabled]]}, next);
|
||||
} else {
|
||||
SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_ENABLED]]}, next);
|
||||
}
|
||||
}
|
||||
function cleanUpTest() {
|
||||
var next = cleanUpTestEnabled;
|
||||
if (testMode) {
|
||||
testMode.done(next);
|
||||
testMode = null;
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
function cleanUpLowMemoryPlatform() {
|
||||
var next = cleanUpTest;
|
||||
if (testMode) {
|
||||
testMode.clearFakeLowMemoryPlatform(next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
function cleanUpExtraParameters() {
|
||||
var next = cleanUpLowMemoryPlatform;
|
||||
if (testMode) {
|
||||
testMode.clearFakeParameters(next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
return new Promise(function(resolve, reject) {
|
||||
self.hw.attach({
|
||||
'pushParameters': function() {
|
||||
self._window.setTimeout(resolve);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
cleanUpExtraParameters();
|
||||
}
|
||||
/* When an error occurs in the promise chain, all of the relevant rejection
|
||||
functions will be triggered. Most of the time however we only want the
|
||||
first rejection to be handled and then let the failure trickle down the
|
||||
chain to terminate the test. There is no way to exit a promise chain
|
||||
early so the convention is to handle the error in the first reject and
|
||||
then give an empty error for subsequent reject handlers so they know
|
||||
it is not for them.
|
||||
|
||||
ise(SpecialPowers.sanityCheck(), "foo", "SpecialPowers passed sanity check");
|
||||
return {
|
||||
begin: testBegin,
|
||||
end: testEnd
|
||||
};
|
||||
For example:
|
||||
function rejectSomething(e) {
|
||||
return suite.logError('something call failed');
|
||||
}
|
||||
|
||||
})();
|
||||
getCamera()
|
||||
.then(, suite.rejectGetCamera)
|
||||
.then(something)
|
||||
.then(, rejectSomething)
|
||||
|
||||
If the getCamera promise is rejected, suite.rejectGetCamera reports an
|
||||
error, but rejectSomething remains silent. */
|
||||
_logError: function(msg, e) {
|
||||
if (isDefined(e)) {
|
||||
ok(false, msg + ': ' + e);
|
||||
}
|
||||
// Make sure the error is undefined for later handlers
|
||||
return Promise.reject();
|
||||
},
|
||||
|
||||
/* The reject handlers below are intended to be used
|
||||
when a test case does not expect a particular call
|
||||
to fail but otherwise does not require any special
|
||||
handling of that situation beyond failing the test
|
||||
case and logging why.*/
|
||||
_rejectGetCamera: function(e) {
|
||||
return this.logError('get camera failed', e);
|
||||
},
|
||||
|
||||
_rejectRelease: function(e) {
|
||||
return this.logError('release camera failed', e);
|
||||
},
|
||||
|
||||
_rejectAutoFocus: function(e) {
|
||||
return this.logError('auto focus failed', e);
|
||||
},
|
||||
|
||||
_rejectTakePicture: function(e) {
|
||||
return this.logError('take picture failed', e);
|
||||
},
|
||||
|
||||
_rejectPreviewStarted: function(e) {
|
||||
return this.logError('preview start failed', e);
|
||||
},
|
||||
|
||||
/* The success handlers below are intended to be used
|
||||
when a test case does not expect a particular call
|
||||
to succed but otherwise does not require any special
|
||||
handling of that situation beyond failing the test
|
||||
case and logging why.*/
|
||||
_expectedError: function(msg) {
|
||||
ok(false, msg);
|
||||
/* Since the original promise was technically resolved
|
||||
we actually want to pass up a rejection to try and
|
||||
end the test case sooner */
|
||||
return Promise.reject();
|
||||
},
|
||||
|
||||
_expectedRejectGetCamera: function(p) {
|
||||
/* Copy handle to ensure it gets released at the end
|
||||
of the test case */
|
||||
self.camera = p.camera;
|
||||
return this.expectedError('expected get camera to fail');
|
||||
},
|
||||
|
||||
_expectedRejectAutoFocus: function(p) {
|
||||
return this.expectedError('expected auto focus to fail');
|
||||
},
|
||||
|
||||
_expectedRejectTakePicture: function(p) {
|
||||
return this.expectedError('expected take picture to fail');
|
||||
},
|
||||
};
|
||||
|
||||
ise(SpecialPowers.sanityCheck(), "foo", "SpecialPowers passed sanity check");
|
||||
|
|
|
@ -12,92 +12,50 @@
|
|||
<img src="#" alt="This image is going to load" id="testimage"/>
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var config = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
suite.test('bug-1022766', function() {
|
||||
function triggerAutoFocus(p) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var firstCall = false;
|
||||
var secondCall = false;
|
||||
|
||||
var Camera = {
|
||||
cameraObj: null,
|
||||
_otherPictureSize: null,
|
||||
get viewfinder() {
|
||||
return document.getElementById('viewfinder');
|
||||
},
|
||||
|
||||
firstCallFailed: false,
|
||||
secondCallSucceeded: false,
|
||||
callbackTriggered: false,
|
||||
checkForDone: function test_checkForDone() {
|
||||
if (Camera.firstCallFailed && Camera.secondCallSucceeded) {
|
||||
ok(Camera.callbackTriggered, "Async callback triggered?");
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
CameraTest.end();
|
||||
}
|
||||
},
|
||||
|
||||
successOne: function test_successOne(focused) {
|
||||
ok(false, "First call to autoFocus() succeeded unexpectedly");
|
||||
},
|
||||
failureOne: function test_failureOne(error) {
|
||||
ok(error.name == "NS_ERROR_IN_PROGRESS", "First call to autoFocus() failed with: "
|
||||
+ error.name);
|
||||
Camera.firstCallFailed = true;
|
||||
Camera.checkForDone();
|
||||
},
|
||||
successTwo: function test_successTwo(focused) {
|
||||
ok(true, "Second call to autoFocus() succeeded");
|
||||
Camera.secondCallSucceeded = true;
|
||||
Camera.checkForDone();
|
||||
},
|
||||
failureTwo: function test_failureTwo(error) {
|
||||
ok(false, "Second call to autoFocus() failed unexpectedly with: " + error);
|
||||
},
|
||||
callback: function test_callback(e) {
|
||||
Camera.cameraObj.removeEventListener('focus', Camera.callback);
|
||||
Camera.callbackTriggered = true;
|
||||
},
|
||||
|
||||
start: function test_start() {
|
||||
function onSuccess(d) {
|
||||
var camera = d.camera;
|
||||
Camera.cameraObj = camera;
|
||||
Camera.viewfinder.mozSrcObject = camera;
|
||||
Camera.viewfinder.play();
|
||||
function end() {
|
||||
if (firstCall && secondCall) {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
// It doesn't matter if the emulator supports focus or not;
|
||||
// this is just testing the sequencing.
|
||||
camera.addEventListener('focus', Camera.callback);
|
||||
camera.autoFocus().then(Camera.successOne, Camera.failureOne);
|
||||
camera.autoFocus().then(Camera.successTwo, Camera.failureTwo);
|
||||
};
|
||||
suite.camera.autoFocus().then(function(p) {
|
||||
ok(false, "First call to autoFocus() succeeded unexpectedly");
|
||||
firstCall = true;
|
||||
end();
|
||||
}, function(e) {
|
||||
ok(e.name === 'NS_ERROR_IN_PROGRESS', 'First call to autoFocus() failed with: ' + e);
|
||||
firstCall = true;
|
||||
end();
|
||||
});
|
||||
|
||||
navigator.mozCameras.getCamera(whichCamera, config).then(onSuccess, onError);
|
||||
suite.camera.autoFocus().then(function(p) {
|
||||
ok(true, "Second call to autoFocus() succeeded");
|
||||
secondCall = true;
|
||||
end();
|
||||
}, function(e) {
|
||||
ok(false, "Second call to autoFocus() failed unexpectedly with: " + e);
|
||||
secondCall = true;
|
||||
end();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
if (Camera.cameraObj) {
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
}
|
||||
return suite.getCamera()
|
||||
.then(triggerAutoFocus, suite.rejectGetCamera)
|
||||
});
|
||||
|
||||
CameraTest.begin("hardware", function(test) {
|
||||
test.set("auto-focus-process-failure", function() {
|
||||
Camera.start();
|
||||
})
|
||||
});
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -193,7 +193,7 @@ var Camera = {
|
|||
t.func(Camera.cameraObj);
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
CameraTest.end();
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
|
|
@ -14,473 +14,382 @@
|
|||
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var initialConfig = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
var cameraObj = null;
|
||||
suite.test('fake-zoom', function() {
|
||||
suite.hw.params['zoom-ratios'] = '100,150,200,300,400';
|
||||
suite.hw.params['max-zoom'] = '4';
|
||||
|
||||
// Shorthand functions
|
||||
function onError(e) {
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
function resolve(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
|
||||
function end() {
|
||||
CameraTest.end();
|
||||
}
|
||||
function next() {
|
||||
if (cameraObj) {
|
||||
cameraObj.release().then(
|
||||
function success() {
|
||||
CameraTest.next();
|
||||
},
|
||||
onError
|
||||
);
|
||||
cameraObj = null;
|
||||
} else {
|
||||
CameraTest.next();
|
||||
}
|
||||
}
|
||||
function run() {
|
||||
CameraTest.run();
|
||||
}
|
||||
ok(cap.zoomRatios.length == 5, "zoom ratios length = " + cap.zoomRatios.length);
|
||||
|
||||
// The array of tests. Because camera capabilities don't change over the life
|
||||
// of a CameraControl object, they are only read once when the CameraControl is
|
||||
// created; so we have to call the 'prep' function first to set the fake
|
||||
// capability pref, before we call getCamera() and call 'test' to run the test.
|
||||
var tests = [
|
||||
{
|
||||
key: "fake-zoom",
|
||||
prep: function setupFakeZoom(test) {
|
||||
test.setFakeParameters("zoom-ratios=100,150,200,300,400;max-zoom=4", function() {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakeZoom(cam, cap) {
|
||||
ok(cap.zoomRatios.length == 5, "zoom ratios length = " + cap.zoomRatios.length);
|
||||
// test individual zoom ratios
|
||||
cap.zoomRatios.forEach(function(zoom, index) {
|
||||
cam.zoom = zoom;
|
||||
ok(cam.zoom === zoom,
|
||||
"zoom[" + index + "] = " + zoom + "x, cam.zoom = " + cam.zoom + "x");
|
||||
});
|
||||
|
||||
// test individual zoom ratios
|
||||
cap.zoomRatios.forEach(function(zoom, index) {
|
||||
cam.zoom = zoom;
|
||||
ok(cam.zoom === zoom,
|
||||
"zoom[" + index + "] = " + zoom + "x, cam.zoom = " + cam.zoom + "x");
|
||||
});
|
||||
// test below-lower-bound zoom ratio
|
||||
var zoom = cap.zoomRatios[0] - 0.1;
|
||||
cam.zoom = zoom;
|
||||
ok(cam.zoom === cap.zoomRatios[0],
|
||||
zoom + "x zoom clamps to minimum: " +
|
||||
cap.zoomRatios[0] + "x, cam.zoom = " + cam.zoom + "x");
|
||||
|
||||
// test below-lower-bound zoom ratio
|
||||
var zoom = cap.zoomRatios[0] - 0.1;
|
||||
// test above-upper-bound zoom ratio
|
||||
zoom = cap.zoomRatios.slice(-1)[0] + 1.0;
|
||||
cam.zoom = zoom;
|
||||
ok(cam.zoom === cap.zoomRatios.slice(-1)[0],
|
||||
zoom + "x zoom clamps to maximum: " + cap.zoomRatios.slice(-1)[0] +
|
||||
"x, cam.zoom = " + cam.zoom + "x");
|
||||
|
||||
// test snapping to supported zoom ratio
|
||||
if (cap.zoomRatios.length > 1) {
|
||||
zoom = (cap.zoomRatios[0] + cap.zoomRatios[1]) / 2;
|
||||
cam.zoom = zoom;
|
||||
ok(cam.zoom === cap.zoomRatios[0],
|
||||
zoom + "x zoom clamps to minimum: " +
|
||||
cap.zoomRatios[0] + "x, cam.zoom = " + cam.zoom + "x");
|
||||
|
||||
// test above-upper-bound zoom ratio
|
||||
zoom = cap.zoomRatios.slice(-1)[0] + 1.0;
|
||||
cam.zoom = zoom;
|
||||
ok(cam.zoom === cap.zoomRatios.slice(-1)[0],
|
||||
zoom + "x zoom clamps to maximum: " + cap.zoomRatios.slice(-1)[0] +
|
||||
zoom + "x zoom rounded down to: " + cap.zoomRatios[0] +
|
||||
"x, cam.zoom = " + cam.zoom + "x");
|
||||
}
|
||||
}
|
||||
|
||||
// test snapping to supported zoom ratio
|
||||
if (cap.zoomRatios.length > 1) {
|
||||
zoom = (cap.zoomRatios[0] + cap.zoomRatios[1]) / 2;
|
||||
cam.zoom = zoom;
|
||||
ok(cam.zoom === cap.zoomRatios[0],
|
||||
zoom + "x zoom rounded down to: " + cap.zoomRatios[0] +
|
||||
"x, cam.zoom = " + cam.zoom + "x");
|
||||
return suite.getCamera()
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
|
||||
suite.test('fake-zoom-out-of-order', function() {
|
||||
// We expect the camera library to give us zoom ratios in order; if
|
||||
// it doesn't we ignore the list and just return 1x support.
|
||||
suite.hw.params['zoom-ratios'] = '100,150,200,400,300';
|
||||
suite.hw.params['max-zoom'] = '4';
|
||||
|
||||
function resolve(p) {
|
||||
var cap = suite.camera.capabilities;
|
||||
ok(cap.zoomRatios.length == 1, "zoom ratios length = " + cap.zoomRatios.length);
|
||||
ok(cap.zoomRatios[0] == 1.0, "only supported zoom = " + cap.zoomRatios[0] + "x");
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
suite.test('fake-high-memory-platform', function() {
|
||||
suite.hw.params['scene-mode-values'] = 'none,snow,beach,hdr,nothdr';
|
||||
|
||||
function resolve(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
ok(cap.sceneModes.length == 5, "scene modes length = " + cap.zoomRatios.length);
|
||||
|
||||
// make sure expected values are present and can be set
|
||||
[ "none", "snow", "beach", "hdr", "nothdr" ].forEach(function(mode) {
|
||||
ok(cap.sceneModes.indexOf(mode) != -1, "Scene mode '" + mode + "' is present");
|
||||
cam.sceneMode = mode;
|
||||
ok(cam.sceneMode == mode, "Scene mode '" + cam.sceneMode + "' is set");
|
||||
});
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
suite.test('fake-low-memory-platform', function() {
|
||||
suite.hw.params['scene-mode-values'] = 'none,hdr,snow,beach,hdr,nothdr';
|
||||
|
||||
function resolve(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
ok(cap.sceneModes.length == 4, "scene modes length = " + cap.zoomRatios.length);
|
||||
|
||||
// make sure expected values are present and can be set
|
||||
[ "none", "snow", "beach", "nothdr" ].forEach(function(mode) {
|
||||
ok(cap.sceneModes.indexOf(mode) != -1, "Scene mode '" + mode + "' is present");
|
||||
cam.sceneMode = mode;
|
||||
ok(cam.sceneMode == mode, "Scene mode '" + cam.sceneMode + "' is set");
|
||||
});
|
||||
|
||||
// make sure unsupported values have been removed, and can't be set
|
||||
var sceneMode = cam.sceneMode;
|
||||
[ "hdr" ].forEach(function(mode) {
|
||||
ok(cap.sceneModes.indexOf(mode) == -1, "Scene mode '" + mode + "' is not present");
|
||||
try {
|
||||
cam.sceneMode = mode;
|
||||
} catch(e) {
|
||||
}
|
||||
ok(cam.sceneMode != mode, "Scene mode '" + cam.sceneMode + "' is still set, '"
|
||||
+ mode + "' rejected");
|
||||
});
|
||||
ok(cam.sceneMode == sceneMode, "Scene mode '" + cam.sceneMode + "' is still set");
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "fake-zoom-out-of-order",
|
||||
prep: function setupFakeZoomOutOfOrder(test) {
|
||||
// We expect the camera library to give us zoom ratios in order; if
|
||||
// it doesn't we ignore the list and just return 1x support.
|
||||
test.setFakeParameters("zoom-ratios=100,150,200,400,300;max-zoom=4", function () {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakeZoomOutOfOrder(cam, cap) {
|
||||
ok(cap.zoomRatios.length == 1, "zoom ratios length = " + cap.zoomRatios.length);
|
||||
ok(cap.zoomRatios[0] == 1.0, "only supported zoom = " + cap.zoomRatios[0] + "x");
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "fake-high-memory-platform",
|
||||
prep: function setupFakeHighMemoryPlatform(test) {
|
||||
test.setFakeParameters("scene-mode-values=none,snow,beach,hdr,nothdr", function () {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakeHighMemoryPlatform(cam, cap) {
|
||||
ok(cap.sceneModes.length == 5, "scene modes length = " + cap.zoomRatios.length);
|
||||
return suite.setLowMemoryPlatform()
|
||||
.then(suite.getCamera)
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
// make sure expected values are present and can be set
|
||||
[ "none", "snow", "beach", "hdr", "nothdr" ].forEach(function(mode) {
|
||||
ok(cap.sceneModes.indexOf(mode) != -1, "Scene mode '" + mode + "' is present");
|
||||
cam.sceneMode = mode;
|
||||
ok(cam.sceneMode == mode, "Scene mode '" + cam.sceneMode + "' is set");
|
||||
});
|
||||
suite.test('fake-iso', function() {
|
||||
suite.hw.params['iso'] = 'auto';
|
||||
suite.hw.params['iso-values'] = 'auto,ISO_HJR,ISO100,foo,ISObar,ISO150moz,ISO200,400,ISO800,1600';
|
||||
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "fake-low-memory-platform",
|
||||
prep: function setupFakeLowMemoryPlatform(test) {
|
||||
test.setFakeLowMemoryPlatform(function() {
|
||||
test.setFakeParameters("scene-mode-values=none,hdr,snow,beach,hdr,nothdr", function () {
|
||||
run();
|
||||
});
|
||||
});
|
||||
},
|
||||
test: function testFakeLowMemoryPlatform(cam, cap) {
|
||||
ok(cap.sceneModes.length == 4, "scene modes length = " + cap.zoomRatios.length);
|
||||
function resolve(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
ok(cap.isoModes.length == 7, "ISO modes length = " + cap.isoModes.length);
|
||||
|
||||
// make sure expected values are present and can be set
|
||||
[ "none", "snow", "beach", "nothdr" ].forEach(function(mode) {
|
||||
ok(cap.sceneModes.indexOf(mode) != -1, "Scene mode '" + mode + "' is present");
|
||||
cam.sceneMode = mode;
|
||||
ok(cam.sceneMode == mode, "Scene mode '" + cam.sceneMode + "' is set");
|
||||
});
|
||||
// make sure we're not leaking any unexpected values formats
|
||||
[ "ISO_HJR", "_HJR", "HJR", "ISO100", "ISO200", "ISO800" ].forEach(function(iso) {
|
||||
ok(cap.isoModes.indexOf(iso) == -1, "ISO mode '" + iso + "' does not appear");
|
||||
});
|
||||
|
||||
// make sure unsupported values have been removed, and can't be set
|
||||
var sceneMode = cam.sceneMode;
|
||||
[ "hdr" ].forEach(function(mode) {
|
||||
ok(cap.sceneModes.indexOf(mode) == -1, "Scene mode '" + mode + "' is not present");
|
||||
try {
|
||||
cam.sceneMode = mode;
|
||||
} catch(e) {
|
||||
// make sure any weird values are dropped entirely
|
||||
[ "foo", "ISObar", "bar", "ISO150moz", "150moz", "150" ].forEach(function(iso) {
|
||||
ok(cap.isoModes.indexOf(iso) == -1, "Unknown ISO mode '" + iso + "' is ignored");
|
||||
});
|
||||
|
||||
// make sure expected values are present
|
||||
[ "auto", "hjr", "100", "200", "400", "800", "1600" ].forEach(function(iso) {
|
||||
ok(cap.isoModes.indexOf(iso) != -1, "ISO mode '" + iso + "' is present");
|
||||
});
|
||||
|
||||
// test setters/getters for individual ISO modes
|
||||
cap.isoModes.forEach(function(iso, index) {
|
||||
cam.iso = iso;
|
||||
ok(cam.iso === iso,
|
||||
"ISO[" + index + "] = " + iso + ", cam.iso = " + cam.iso);
|
||||
});
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
suite.test('fake-metering-areas', function() {
|
||||
suite.hw.params['max-num-metering-areas'] = '1';
|
||||
|
||||
function resolve(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
|
||||
ok(cap.maxMeteringAreas == 1, "maxMeteringAreas = " + cap.maxMeteringAreas);
|
||||
cam.setMeteringAreas([
|
||||
{top: -500, bottom: 500, left: -500, right: 500, weight: 100}
|
||||
]);
|
||||
areas = cam.getMeteringAreas();
|
||||
ok(areas.length == 1, "areas length = " + areas.length);
|
||||
ok(areas[0].top == -500, "area[0] top = " + areas[0].top);
|
||||
ok(areas[0].bottom == 500, "area[0] bottom = " + areas[0].bottom);
|
||||
ok(areas[0].left == -500, "area[0] left = " + areas[0].left);
|
||||
ok(areas[0].right == 500, "area[0] right = " + areas[0].right);
|
||||
ok(areas[0].weight == 100, "area[0] weight = " + areas[0].weight);
|
||||
cam.setMeteringAreas([
|
||||
{top: -501, bottom: 502, left: -503, right: 504, weight: 105},
|
||||
{top: -500, bottom: 500, left: -500, right: 500, weight: 100}
|
||||
]);
|
||||
areas = cam.getMeteringAreas();
|
||||
ok(areas.length == 1, "areas length = " + areas.length);
|
||||
ok(areas[0].top == -501, "area[0] top = " + areas[0].top);
|
||||
ok(areas[0].bottom == 502, "area[0] bottom = " + areas[0].bottom);
|
||||
ok(areas[0].left == -503, "area[0] left = " + areas[0].left);
|
||||
ok(areas[0].right == 504, "area[0] right = " + areas[0].right);
|
||||
ok(areas[0].weight == 105, "area[0] weight = " + areas[0].weight);
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
suite.test('fake-focus-areas', function() {
|
||||
suite.hw.params['max-num-focus-areas'] = '1';
|
||||
|
||||
function resolve(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
|
||||
ok(cap.maxFocusAreas == 1, "maxFocusAreas = " + cap.maxFocusAreas);
|
||||
cam.setFocusAreas([
|
||||
{top: -500, bottom: 500, left: -500, right: 500, weight: 100}
|
||||
]);
|
||||
areas = cam.getFocusAreas();
|
||||
ok(areas.length == 1, "areas length = " + areas.length);
|
||||
ok(areas[0].top == -500, "area[0] top = " + areas[0].top);
|
||||
ok(areas[0].bottom == 500, "area[0] bottom = " + areas[0].bottom);
|
||||
ok(areas[0].left == -500, "area[0] left = " + areas[0].left);
|
||||
ok(areas[0].right == 500, "area[0] right = " + areas[0].right);
|
||||
ok(areas[0].weight == 100, "area[0] weight = " + areas[0].weight);
|
||||
cam.setFocusAreas([
|
||||
{top: -501, bottom: 502, left: -503, right: 504, weight: 105},
|
||||
{top: -500, bottom: 500, left: -500, right: 500, weight: 100}
|
||||
]);
|
||||
areas = cam.getFocusAreas();
|
||||
ok(areas.length == 1, "areas length = " + areas.length);
|
||||
ok(areas[0].top == -501, "area[0] top = " + areas[0].top);
|
||||
ok(areas[0].bottom == 502, "area[0] bottom = " + areas[0].bottom);
|
||||
ok(areas[0].left == -503, "area[0] left = " + areas[0].left);
|
||||
ok(areas[0].right == 504, "area[0] right = " + areas[0].right);
|
||||
ok(areas[0].weight == 105, "area[0] weight = " + areas[0].weight);
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
suite.test('fake-exposure-compensation', function() {
|
||||
suite.hw.params['max-num-focus-areas'] = '1';
|
||||
suite.hw.params['exposure-compensation'] = '-1';
|
||||
suite.hw.params['max-exposure-compensation'] = '6';
|
||||
suite.hw.params['min-exposure-compensation'] = '-6';
|
||||
suite.hw.params['exposure-compensation-step'] = '0.5'
|
||||
|
||||
function resolve(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
|
||||
ok(cap.exposureCompensationStep == 0.5,
|
||||
"exposureCompensationStep = " + cap.exposureCompensationStep);
|
||||
ok(cap.minExposureCompensation == -3.0,
|
||||
"minExposureCompensation = " + cap.minExposureCompensation);
|
||||
ok(cap.maxExposureCompensation == 3.0,
|
||||
"maxExposureCompensation = " + cap.maxExposureCompensation);
|
||||
ok(cam.exposureCompensation == -0.5,
|
||||
"exposureCompensation = " + cam.exposureCompensation);
|
||||
|
||||
// Check normal values
|
||||
cam.exposureCompensation = 0.0;
|
||||
ok(cam.exposureCompensation == 0.0,
|
||||
"exposureCompensation = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = cap.minExposureCompensation;
|
||||
ok(cam.exposureCompensation == cap.minExposureCompensation,
|
||||
"exposureCompensation(min) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = cap.maxExposureCompensation;
|
||||
ok(cam.exposureCompensation == cap.maxExposureCompensation,
|
||||
"exposureCompensation(max) = " + cam.exposureCompensation);
|
||||
|
||||
// Rounding
|
||||
cam.exposureCompensation = 1.24;
|
||||
ok(cam.exposureCompensation == 1.0,
|
||||
"exposureCompensation(1.24) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = 1.25;
|
||||
ok(cam.exposureCompensation == 1.5,
|
||||
"exposureCompensation(1.25) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = -1.24;
|
||||
ok(cam.exposureCompensation == -1.0,
|
||||
"exposureCompensation(-1.24) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = -1.25;
|
||||
ok(cam.exposureCompensation == -1.5,
|
||||
"exposureCompensation(-1.25) = " + cam.exposureCompensation);
|
||||
// Check out-of-bounds values
|
||||
cam.exposureCompensation = cap.minExposureCompensation - 1.0;
|
||||
ok(cam.exposureCompensation == cap.minExposureCompensation,
|
||||
"exposureCompensation(min - 1.0) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = cap.maxExposureCompensation + 1.0;
|
||||
ok(cam.exposureCompensation == cap.maxExposureCompensation,
|
||||
"exposureCompensation(max + 1.0) = " + cam.exposureCompensation);
|
||||
|
||||
// Check extreme values
|
||||
cam.exposureCompensation = -1 * Math.pow(2, 32);
|
||||
ok(cam.exposureCompensation == cap.minExposureCompensation,
|
||||
"exposureCompensation(-2^32) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = Math.pow(2, 32);
|
||||
ok(cam.exposureCompensation == cap.maxExposureCompensation,
|
||||
"exposureCompensation(2^32) = " + cam.exposureCompensation);
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
suite.test('bug-1054803', function() {
|
||||
// The important part of this test is that 3264 * 1836 = 5,992,704 = 2448 * 2448,
|
||||
// so we need to make sure that the size-matching algorithm picks the right size.
|
||||
suite.hw.params['picture-size-values'] = '3264x1836,2448x2448,1836x3264';
|
||||
|
||||
function verify(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
|
||||
var expSizes = [ { height: 3264, width: 1836 },
|
||||
{ height: 1836, width: 3264 },
|
||||
{ height: 2448, width: 2448 } ];
|
||||
|
||||
// validate the capability attribute
|
||||
ok(cap.pictureSizes.length == expSizes.length, "pictureSizes.length = " + cap.pictureSizes.length);
|
||||
var found = 0;
|
||||
expSizes.forEach(function(size) {
|
||||
found = 0;
|
||||
cap.pictureSizes.forEach(function(capSize) {
|
||||
if (capSize.height == size.height && capSize.width == size.width) {
|
||||
++found;
|
||||
}
|
||||
ok(cam.sceneMode != mode, "Scene mode '" + cam.sceneMode + "' is still set, '"
|
||||
+ mode + "' rejected");
|
||||
});
|
||||
ok(cam.sceneMode == sceneMode, "Scene mode '" + cam.sceneMode + "' is still set");
|
||||
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "fake-iso",
|
||||
prep: function setupFakeIso(test) {
|
||||
// we should recognize 'auto', 'hjr', and numeric modes; anything else
|
||||
// from the driver is ignored, which this test also verifies.
|
||||
test.setFakeParameters(
|
||||
"iso=auto;iso-values=auto,ISO_HJR,ISO100,foo,ISObar,ISO150moz,ISO200,400,ISO800,1600",
|
||||
function () {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakeIso(cam, cap) {
|
||||
ok(cap.isoModes.length == 7, "ISO modes length = " + cap.isoModes.length);
|
||||
|
||||
// make sure we're not leaking any unexpected values formats
|
||||
[ "ISO_HJR", "_HJR", "HJR", "ISO100", "ISO200", "ISO800" ].forEach(function(iso) {
|
||||
ok(cap.isoModes.indexOf(iso) == -1, "ISO mode '" + iso + "' does not appear");
|
||||
});
|
||||
|
||||
// make sure any weird values are dropped entirely
|
||||
[ "foo", "ISObar", "bar", "ISO150moz", "150moz", "150" ].forEach(function(iso) {
|
||||
ok(cap.isoModes.indexOf(iso) == -1, "Unknown ISO mode '" + iso + "' is ignored");
|
||||
});
|
||||
|
||||
// make sure expected values are present
|
||||
[ "auto", "hjr", "100", "200", "400", "800", "1600" ].forEach(function(iso) {
|
||||
ok(cap.isoModes.indexOf(iso) != -1, "ISO mode '" + iso + "' is present");
|
||||
});
|
||||
|
||||
// test setters/getters for individual ISO modes
|
||||
cap.isoModes.forEach(function(iso, index) {
|
||||
cam.iso = iso;
|
||||
ok(cam.iso === iso,
|
||||
"ISO[" + index + "] = " + iso + ", cam.iso = " + cam.iso);
|
||||
});
|
||||
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "fake-metering-areas",
|
||||
prep: function setupFakeMeteringAreas(test) {
|
||||
test.setFakeParameters("max-num-metering-areas=1", function () {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakeMeteringAreas(cam, cap) {
|
||||
ok(cap.maxMeteringAreas == 1, "maxMeteringAreas = " + cap.maxMeteringAreas);
|
||||
cam.setMeteringAreas([
|
||||
{top: -500, bottom: 500, left: -500, right: 500, weight: 100}
|
||||
]);
|
||||
areas = cam.getMeteringAreas();
|
||||
ok(areas.length == 1, "areas length = " + areas.length);
|
||||
ok(areas[0].top == -500, "area[0] top = " + areas[0].top);
|
||||
ok(areas[0].bottom == 500, "area[0] bottom = " + areas[0].bottom);
|
||||
ok(areas[0].left == -500, "area[0] left = " + areas[0].left);
|
||||
ok(areas[0].right == 500, "area[0] right = " + areas[0].right);
|
||||
ok(areas[0].weight == 100, "area[0] weight = " + areas[0].weight);
|
||||
cam.setMeteringAreas([
|
||||
{top: -501, bottom: 502, left: -503, right: 504, weight: 105},
|
||||
{top: -500, bottom: 500, left: -500, right: 500, weight: 100}
|
||||
]);
|
||||
areas = cam.getMeteringAreas();
|
||||
ok(areas.length == 1, "areas length = " + areas.length);
|
||||
ok(areas[0].top == -501, "area[0] top = " + areas[0].top);
|
||||
ok(areas[0].bottom == 502, "area[0] bottom = " + areas[0].bottom);
|
||||
ok(areas[0].left == -503, "area[0] left = " + areas[0].left);
|
||||
ok(areas[0].right == 504, "area[0] right = " + areas[0].right);
|
||||
ok(areas[0].weight == 105, "area[0] weight = " + areas[0].weight);
|
||||
|
||||
next();
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "fake-focus-areas",
|
||||
prep: function setupFakeFocusAreas(test) {
|
||||
test.setFakeParameters("max-num-focus-areas=1", function () {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakeFocusAreas(cam, cap) {
|
||||
ok(cap.maxFocusAreas == 1, "maxFocusAreas = " + cap.maxFocusAreas);
|
||||
cam.setFocusAreas([
|
||||
{top: -500, bottom: 500, left: -500, right: 500, weight: 100}
|
||||
]);
|
||||
areas = cam.getFocusAreas();
|
||||
ok(areas.length == 1, "areas length = " + areas.length);
|
||||
ok(areas[0].top == -500, "area[0] top = " + areas[0].top);
|
||||
ok(areas[0].bottom == 500, "area[0] bottom = " + areas[0].bottom);
|
||||
ok(areas[0].left == -500, "area[0] left = " + areas[0].left);
|
||||
ok(areas[0].right == 500, "area[0] right = " + areas[0].right);
|
||||
ok(areas[0].weight == 100, "area[0] weight = " + areas[0].weight);
|
||||
cam.setFocusAreas([
|
||||
{top: -501, bottom: 502, left: -503, right: 504, weight: 105},
|
||||
{top: -500, bottom: 500, left: -500, right: 500, weight: 100}
|
||||
]);
|
||||
areas = cam.getFocusAreas();
|
||||
ok(areas.length == 1, "areas length = " + areas.length);
|
||||
ok(areas[0].top == -501, "area[0] top = " + areas[0].top);
|
||||
ok(areas[0].bottom == 502, "area[0] bottom = " + areas[0].bottom);
|
||||
ok(areas[0].left == -503, "area[0] left = " + areas[0].left);
|
||||
ok(areas[0].right == 504, "area[0] right = " + areas[0].right);
|
||||
ok(areas[0].weight == 105, "area[0] weight = " + areas[0].weight);
|
||||
|
||||
next();
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "fake-exposure-compensation",
|
||||
prep: function setupFakeExposureCompensation(test) {
|
||||
test.setFakeParameters("exposure-compensation=-1;max-exposure-compensation=6;min-exposure-compensation=-6;exposure-compensation-step=0.5", function () {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakeFocusAreas(cam, cap) {
|
||||
ok(cap.exposureCompensationStep == 0.5,
|
||||
"exposureCompensationStep = " + cap.exposureCompensationStep);
|
||||
ok(cap.minExposureCompensation == -3.0,
|
||||
"minExposureCompensation = " + cap.minExposureCompensation);
|
||||
ok(cap.maxExposureCompensation == 3.0,
|
||||
"maxExposureCompensation = " + cap.maxExposureCompensation);
|
||||
ok(cam.exposureCompensation == -0.5,
|
||||
"exposureCompensation = " + cam.exposureCompensation);
|
||||
|
||||
// Check normal values
|
||||
cam.exposureCompensation = 0.0;
|
||||
ok(cam.exposureCompensation == 0.0,
|
||||
"exposureCompensation = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = cap.minExposureCompensation;
|
||||
ok(cam.exposureCompensation == cap.minExposureCompensation,
|
||||
"exposureCompensation(min) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = cap.maxExposureCompensation;
|
||||
ok(cam.exposureCompensation == cap.maxExposureCompensation,
|
||||
"exposureCompensation(max) = " + cam.exposureCompensation);
|
||||
|
||||
// Rounding
|
||||
cam.exposureCompensation = 1.24;
|
||||
ok(cam.exposureCompensation == 1.0,
|
||||
"exposureCompensation(1.24) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = 1.25;
|
||||
ok(cam.exposureCompensation == 1.5,
|
||||
"exposureCompensation(1.25) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = -1.24;
|
||||
ok(cam.exposureCompensation == -1.0,
|
||||
"exposureCompensation(-1.24) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = -1.25;
|
||||
ok(cam.exposureCompensation == -1.5,
|
||||
"exposureCompensation(-1.25) = " + cam.exposureCompensation);
|
||||
// Check out-of-bounds values
|
||||
cam.exposureCompensation = cap.minExposureCompensation - 1.0;
|
||||
ok(cam.exposureCompensation == cap.minExposureCompensation,
|
||||
"exposureCompensation(min - 1.0) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = cap.maxExposureCompensation + 1.0;
|
||||
ok(cam.exposureCompensation == cap.maxExposureCompensation,
|
||||
"exposureCompensation(max + 1.0) = " + cam.exposureCompensation);
|
||||
|
||||
// Check extreme values
|
||||
cam.exposureCompensation = -1 * Math.pow(2, 32);
|
||||
ok(cam.exposureCompensation == cap.minExposureCompensation,
|
||||
"exposureCompensation(-2^32) = " + cam.exposureCompensation);
|
||||
cam.exposureCompensation = Math.pow(2, 32);
|
||||
ok(cam.exposureCompensation == cap.maxExposureCompensation,
|
||||
"exposureCompensation(2^32) = " + cam.exposureCompensation);
|
||||
|
||||
next();
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "bug-1054803",
|
||||
prep: function setupFakePictureSizes(test) {
|
||||
// The important part of this test is that 3264 * 1836 = 5,992,704 = 2448 * 2448,
|
||||
// so we need to make sure that the size-matching algorithm picks the right size.
|
||||
test.setFakeParameters("picture-size-values=3264x1836,2448x2448,1836x3264", function () {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakePictureSizes(cam, cap) {
|
||||
// validate the capability attribute
|
||||
ok(cap.pictureSizes.length == 3, "pictureSizes.length = " + cap.pictureSizes.length);
|
||||
var found = 0;
|
||||
[ { height: 3264, width: 1836 },
|
||||
{ height: 1836, width: 3264 },
|
||||
{ height: 2448, width: 2448 } ].forEach(function(size) {
|
||||
found = 0;
|
||||
cap.pictureSizes.forEach(function(capSize) {
|
||||
if (capSize.height == size.height && capSize.width == size.width) {
|
||||
++found;
|
||||
}
|
||||
});
|
||||
ok(found == 1, "found size " + size.toSource() + " in pictureSizes");
|
||||
});
|
||||
|
||||
// test setters and getters
|
||||
var sync = new Promise(function(resolve, reject) {
|
||||
// Use setConfiguration() (which will fail on the profile)
|
||||
// to signify that the CameraControl thread has run and our
|
||||
// settings are applied. Yes--this is an ugly hack.
|
||||
cam.setConfiguration({ mode: 'video',
|
||||
recorderProfile: 'weird-unsupported-profile'
|
||||
}).then(resolve, resolve);
|
||||
});
|
||||
var sizeGenerator = function() {
|
||||
var sizes = [ { height: 3264, width: 1836 },
|
||||
{ height: 1836, width: 3264 },
|
||||
{ height: 2448, width: 2448 } ];
|
||||
for (var i = 0; i < sizes.length; ++i) {
|
||||
yield sizes[i];
|
||||
}
|
||||
}();
|
||||
ok(found == 1, "found size " + size.toSource() + " in pictureSizes");
|
||||
});
|
||||
|
||||
var sizeGenerator = Iterator(expSizes);
|
||||
return new Promise(function(resolve, reject) {
|
||||
function nextSize() {
|
||||
try {
|
||||
var size = sizeGenerator.next();
|
||||
var size = sizeGenerator.next()[1];
|
||||
var sync = suite.waitParameterPush();
|
||||
cam.setPictureSize(size);
|
||||
sync.then(function() {
|
||||
var got = cam.getPictureSize();
|
||||
ok(got.width == size.width && got.height == size.height,
|
||||
"Set size " + size.toSource() + ", got size " + got.toSource());
|
||||
nextSize();
|
||||
}, onError);
|
||||
}, reject);
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
next();
|
||||
resolve();
|
||||
} else {
|
||||
throw e;
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextSize();
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "bug-1052851",
|
||||
prep: function setupFakeMetering(test) {
|
||||
// We should reject duplicate values.
|
||||
test.setFakeParameters(
|
||||
"auto-exposure=frame-average;auto-exposure-values=spot,frame-average,center-weighted,spot,center-weighted",
|
||||
function () {
|
||||
run();
|
||||
});
|
||||
},
|
||||
test: function testFakeMetering(cam, cap) {
|
||||
ok(cap.meteringModes.length == 3, "Metering modes length = " + cap.meteringModes.length);
|
||||
|
||||
// make sure expected values are present
|
||||
[ "spot", "frame-average", "center-weighted" ].forEach(function(mode) {
|
||||
ok(cap.meteringModes.indexOf(mode) != -1, "Metering mode '" + mode + "' is present");
|
||||
});
|
||||
|
||||
// test setters/getters for individual metering modes
|
||||
cap.meteringModes.forEach(function(mode, index) {
|
||||
cam.meteringMode = mode;
|
||||
ok(cam.meteringMode === mode,
|
||||
"Metering Mode[" + index + "] = " + mode + ", cam.meteringMode = " + cam.meteringMode);
|
||||
});
|
||||
|
||||
next();
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var testGenerator = function() {
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
yield tests[i];
|
||||
});
|
||||
}
|
||||
}();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
document.getElementById('viewfinder').mozSrcObject = null;
|
||||
if (cameraObj) {
|
||||
cameraObj.release();
|
||||
cameraObj = null;
|
||||
}
|
||||
return suite.getCamera()
|
||||
.then(verify, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
CameraTest.begin("hardware", function(test) {
|
||||
function onError(error) {
|
||||
ok(false, "getCamera() failed with: " + error);
|
||||
end();
|
||||
suite.test('bug-1052851', function() {
|
||||
// We should reject duplicate values.
|
||||
suite.hw.params['auto-exposure'] = 'frame-average';
|
||||
suite.hw.params['auto-exposure-values'] = 'spot,frame-average,center-weighted,spot,center-weighted';
|
||||
|
||||
function resolve(p) {
|
||||
var cam = suite.camera;
|
||||
var cap = cam.capabilities;
|
||||
|
||||
ok(cap.meteringModes.length == 3, "Metering modes length = " + cap.meteringModes.length);
|
||||
|
||||
// make sure expected values are present
|
||||
[ "spot", "frame-average", "center-weighted" ].forEach(function(mode) {
|
||||
ok(cap.meteringModes.indexOf(mode) != -1, "Metering mode '" + mode + "' is present");
|
||||
});
|
||||
|
||||
// test setters/getters for individual metering modes
|
||||
cap.meteringModes.forEach(function(mode, index) {
|
||||
cam.meteringMode = mode;
|
||||
ok(cam.meteringMode === mode,
|
||||
"Metering Mode[" + index + "] = " + mode + ", cam.meteringMode = " + cam.meteringMode);
|
||||
});
|
||||
}
|
||||
|
||||
CameraTest.next = function() {
|
||||
try {
|
||||
var t = testGenerator.next();
|
||||
info("test: " + t.key);
|
||||
function onSuccess(d) {
|
||||
cameraObj = d.camera;
|
||||
document.getElementById('viewfinder').mozSrcObject = d.camera;
|
||||
var onPreviewStateChange = function (evt) {
|
||||
if (evt.newState === "started") {
|
||||
cameraObj.removeEventListener('previewstatechange', onPreviewStateChange);
|
||||
t.test(cameraObj, cameraObj.capabilities);
|
||||
}
|
||||
};
|
||||
cameraObj.addEventListener('previewstatechange', onPreviewStateChange);
|
||||
}
|
||||
CameraTest.run = function() {
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
|
||||
};
|
||||
t.prep(test);
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
end();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
next();
|
||||
return suite.getCamera()
|
||||
.then(resolve, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -17,104 +17,29 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=965421
|
|||
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var initialConfig = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
const PREF_AUTOFOCUSCALLBACK_ENABLED = "camera.control.autofocus_moving_callback.enabled";
|
||||
|
||||
var cameraObj;
|
||||
var oldPref;
|
||||
|
||||
// Shorthand functions
|
||||
function end() {
|
||||
function reallyEnd() {
|
||||
CameraTest.end();
|
||||
}
|
||||
if (oldPref) {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set': [[PREF_AUTOFOCUSCALLBACK_ENABLED, oldPref]]}, reallyEnd);
|
||||
} else {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'clear': [[PREF_AUTOFOCUSCALLBACK_ENABLED]]}, reallyEnd);
|
||||
}
|
||||
}
|
||||
function next() {
|
||||
CameraTest.next();
|
||||
}
|
||||
|
||||
var tests = [
|
||||
{
|
||||
key: "autofocus-moving-true",
|
||||
func: function testAutoFocusMovingIsTrue(camera) {
|
||||
var handler = function(evt) {
|
||||
camera.removeEventListener("focus", handler);
|
||||
ok(evt.newState == "focusing", "autofocus event state focusing == " + evt.newState);
|
||||
camera.focusMode = 'auto';
|
||||
next();
|
||||
suite.test('auto-focus-moving', function() {
|
||||
function triggerAutoFocusMoving(p) {
|
||||
var sync = new Promise(function(resolve, reject) {
|
||||
function onEvent(e) {
|
||||
suite.camera.removeEventListener('focus', onEvent);
|
||||
ok(e.newState === 'focusing', 'autofocus event state focusing == ' + e.newState);
|
||||
resolve();
|
||||
}
|
||||
camera.addEventListener("focus", handler);
|
||||
camera.focusMode = 'continuous-picture';
|
||||
}
|
||||
},
|
||||
];
|
||||
suite.camera.addEventListener('focus', onEvent);
|
||||
});
|
||||
|
||||
var testGenerator = function() {
|
||||
for (var i = 0; i < tests.length; ++i ) {
|
||||
yield tests[i];
|
||||
suite.hw.fireAutoFocusMoving(true);
|
||||
return sync;
|
||||
}
|
||||
}();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
document.getElementById('viewfinder').mozSrcObject = null;
|
||||
cameraObj.release();
|
||||
cameraObj = null;
|
||||
return suite.getCamera()
|
||||
.then(triggerAutoFocusMoving);
|
||||
});
|
||||
|
||||
// Must call CameraTest.begin() before any other async methods.
|
||||
CameraTest.begin("hardware", function(test) {
|
||||
// If the pref doesn't exist, this get will fail; catch it and continue.
|
||||
try {
|
||||
oldPref = SpecialPowers.getBoolPref(PREF_AUTOFOCUSCALLBACK_ENABLED);
|
||||
} catch(e) { }
|
||||
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_AUTOFOCUSCALLBACK_ENABLED, true]]}, function() {
|
||||
var enabled;
|
||||
try {
|
||||
enabled = SpecialPowers.getBoolPref(PREF_AUTOFOCUSCALLBACK_ENABLED);
|
||||
} catch(e) { }
|
||||
ok(enabled, PREF_AUTOFOCUSCALLBACK_ENABLED + " is " + enabled);
|
||||
|
||||
function onSuccess(d) {
|
||||
document.getElementById('viewfinder').mozSrcObject = d.camera;
|
||||
cameraObj = d.camera;
|
||||
CameraTest.next = function() {
|
||||
try {
|
||||
var t = testGenerator.next();
|
||||
test.set(t.key, t.func.bind(undefined, d.camera));
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
end();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
next();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "getCamera() failed with: " + error);
|
||||
end();
|
||||
}
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
|
||||
})
|
||||
});
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -17,38 +17,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=965420
|
|||
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var initialConfig = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
|
||||
const PREF_FACEDETECTION_ENABLED = "camera.control.face_detection.enabled";
|
||||
|
||||
var cameraObj;
|
||||
var oldPref;
|
||||
|
||||
// Shorthand functions
|
||||
function end() {
|
||||
function reallyEnd() {
|
||||
CameraTest.end();
|
||||
}
|
||||
if (oldPref) {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set': [[PREF_FACEDETECTION_ENABLED, oldPref]]}, reallyEnd);
|
||||
} else {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'clear': [[PREF_FACEDETECTION_ENABLED]]}, reallyEnd);
|
||||
}
|
||||
}
|
||||
function next() {
|
||||
CameraTest.next();
|
||||
}
|
||||
|
||||
function compareFaces(aFaces, expected)
|
||||
{
|
||||
ok(aFaces, "have detected faces object");
|
||||
|
@ -122,11 +90,31 @@ function compareFace(aFace, expected)
|
|||
return "ok";
|
||||
}
|
||||
|
||||
var tests = [
|
||||
{
|
||||
key: "face-detection-detected-one-face",
|
||||
func: function testFaceDetectionFoundOneFace(camera) {
|
||||
var expected = {
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
suite.test('face-detection', function() {
|
||||
function detectFace(msg, expected) {
|
||||
var sync = new Promise(function(resolve, reject) {
|
||||
function onEvent(evt) {
|
||||
try {
|
||||
suite.camera.removeEventListener('facesdetected', onEvent);
|
||||
ok(compareFaces(evt.faces, expected),
|
||||
"facedetected event received " + msg + " correctly");
|
||||
resolve();
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
suite.camera.addEventListener('facesdetected', onEvent);
|
||||
});
|
||||
|
||||
suite.hw.fireFacesDetected(expected);
|
||||
return sync;
|
||||
}
|
||||
|
||||
function detectOneFace(p) {
|
||||
return detectFace('one-face',
|
||||
{
|
||||
faces: [ {
|
||||
id: 1,
|
||||
score: 2,
|
||||
|
@ -149,24 +137,13 @@ var tests = [
|
|||
y: 12
|
||||
}
|
||||
} ]
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var handler = function(evt) {
|
||||
ok(compareFaces(evt.faces, expected),
|
||||
"facedetected event received the detected faces correctly");
|
||||
camera.stopFaceDetection();
|
||||
camera.removeEventListener('facesdetected', handler);
|
||||
next();
|
||||
};
|
||||
|
||||
camera.addEventListener('facesdetected', handler);
|
||||
camera.startFaceDetection();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "face-detection-detected-two-faces",
|
||||
func: function testFaceDetectionFoundTwoFace(camera) {
|
||||
var expected = {
|
||||
function detectTwoFaces(p) {
|
||||
return detectFace('two-faces',
|
||||
{
|
||||
faces: [ {
|
||||
id: 1,
|
||||
score: 2,
|
||||
|
@ -211,24 +188,13 @@ var tests = [
|
|||
y: 24
|
||||
}
|
||||
} ]
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var handler = function(evt) {
|
||||
ok(compareFaces(evt.faces, expected),
|
||||
"facedetected event received the detected faces correctly");
|
||||
camera.stopFaceDetection();
|
||||
camera.removeEventListener('facesdetected', handler);
|
||||
next();
|
||||
};
|
||||
|
||||
camera.addEventListener('facesdetected', handler);
|
||||
camera.startFaceDetection();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "face-detection-detected-one-face-no-features",
|
||||
func: function (camera) {
|
||||
var expected = {
|
||||
function detectOneFaceNoFeatures() {
|
||||
return detectFace('one-face-no-features',
|
||||
{
|
||||
faces: [ {
|
||||
id: 1,
|
||||
score: 100,
|
||||
|
@ -242,93 +208,27 @@ var tests = [
|
|||
rightEye: null,
|
||||
mouth: null
|
||||
} ]
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var handler = function(evt) {
|
||||
ok(compareFaces(evt.faces, expected),
|
||||
"facedetected event received the detected faces correctly");
|
||||
camera.stopFaceDetection();
|
||||
camera.removeEventListener('facesdetected', handler);
|
||||
next();
|
||||
};
|
||||
|
||||
camera.addEventListener('facesdetected', handler);
|
||||
camera.startFaceDetection();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "face-detection-no-faces-detected",
|
||||
func: function (camera) {
|
||||
var expected = {
|
||||
function detectNoFaces() {
|
||||
return detectFace('no-faces',
|
||||
{
|
||||
faces: []
|
||||
};
|
||||
|
||||
var handler = function(evt) {
|
||||
ok(compareFaces(evt.faces, expected),
|
||||
"facedetected event received the detected faces correctly");
|
||||
camera.stopFaceDetection();
|
||||
camera.removeEventListener('facesdetected', handler);
|
||||
next();
|
||||
};
|
||||
|
||||
camera.addEventListener('facesdetected', handler);
|
||||
camera.startFaceDetection();
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var testGenerator = function() {
|
||||
for (var i = 0; i < tests.length; ++i ) {
|
||||
yield tests[i];
|
||||
}
|
||||
);
|
||||
}
|
||||
}();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
document.getElementById('viewfinder').mozSrcObject = null;
|
||||
if (cameraObj) {
|
||||
cameraObj.release();
|
||||
cameraObj = null;
|
||||
}
|
||||
return suite.getCamera()
|
||||
.then(detectOneFace, suite.rejectGetCamera)
|
||||
.then(detectTwoFaces)
|
||||
.then(detectOneFaceNoFeatures)
|
||||
.then(detectNoFaces);
|
||||
});
|
||||
|
||||
// Must call CameraTest.begin() before any other async methods.
|
||||
CameraTest.begin("hardware", function(test) {
|
||||
// If the pref doesn't exist, this get will fail; catch it and continue.
|
||||
try {
|
||||
oldPref = SpecialPowers.getBoolPref(PREF_FACEDETECTION_ENABLED);
|
||||
} catch(e) { }
|
||||
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_FACEDETECTION_ENABLED, true]]}, function() {
|
||||
var enabled;
|
||||
try {
|
||||
enabled = SpecialPowers.getBoolPref(PREF_FACEDETECTION_ENABLED);
|
||||
} catch(e) { }
|
||||
ok(enabled, PREF_FACEDETECTION_ENABLED + " is " + enabled);
|
||||
|
||||
function onSuccess(d) {
|
||||
cameraObj = d.camera;
|
||||
document.getElementById('viewfinder').mozSrcObject = cameraObj;
|
||||
CameraTest.next = function() {
|
||||
try {
|
||||
var t = testGenerator.next();
|
||||
test.set(t.key, t.func.bind(undefined, cameraObj));
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
end();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
next();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "getCamera() failed with: " + error);
|
||||
end();
|
||||
}
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
|
||||
})
|
||||
});
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -17,128 +17,156 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=940424
|
|||
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var initialConfig = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
/* Each discrete test case can be added to the test queue here.
|
||||
They won't be run until you call suite setup and run. */
|
||||
suite.test('auto-focus-failures', function() {
|
||||
function startAutoFocusFail(p) {
|
||||
suite.hw.attach({
|
||||
autoFocus: function() {
|
||||
suite.hw.fireAutoFocusComplete(false);
|
||||
}
|
||||
});
|
||||
return suite.camera.autoFocus();
|
||||
}
|
||||
};
|
||||
|
||||
var cameraObj;
|
||||
|
||||
// Shorthand functions
|
||||
function end() {
|
||||
CameraTest.end();
|
||||
}
|
||||
function next() {
|
||||
CameraTest.next();
|
||||
}
|
||||
|
||||
// The array of tests
|
||||
var tests = [
|
||||
{
|
||||
key: "auto-focus-failure",
|
||||
func: function testAutoFocusApiFailure(camera) {
|
||||
function onSuccess(success) {
|
||||
ok(false, "autoFocus() succeeded incorrectly");
|
||||
end();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "autoFocus() failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.autoFocus().then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "auto-focus-process-failure",
|
||||
func: function testAutoFocusProcessFailure(camera) {
|
||||
function onSuccess(success) {
|
||||
if (success) {
|
||||
ok(false, "autoFocus() process succeeded incorrectly");
|
||||
end();
|
||||
} else {
|
||||
ok(true, "autoFocus() process failed correctly");
|
||||
next();
|
||||
}
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "autoFocus() process failed incorrectly with: " + error);
|
||||
end();
|
||||
}
|
||||
camera.autoFocus().then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "take-picture-failure",
|
||||
func: function testTakePictureApiFailure(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "takePicture() succeeded incorrectly");
|
||||
end();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "takePicture() failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.takePicture(null).then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "take-picture-process-failure",
|
||||
func: function testTakePictureProcessFailure(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "takePicture() process succeeded incorrectly");
|
||||
end();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "takePicture() process failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.takePicture(null).then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var testGenerator = function() {
|
||||
for (var i = 0; i < tests.length; ++i ) {
|
||||
yield tests[i];
|
||||
function resolveAutoFocusFail(focused) {
|
||||
ok(!focused, 'autoFocus() should be unfocused: ' + focused);
|
||||
}
|
||||
}();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
document.getElementById('viewfinder').mozSrcObject = null;
|
||||
cameraObj.release();
|
||||
cameraObj = null;
|
||||
function startAutoFocusError(p) {
|
||||
suite.hw.attach({
|
||||
autoFocus: function() {
|
||||
throw SpecialPowers.Cr.NS_ERROR_FAILURE;
|
||||
}
|
||||
});
|
||||
return suite.camera.autoFocus();
|
||||
}
|
||||
|
||||
function rejectAutoFocusError(e) {
|
||||
ok(e.name === 'NS_ERROR_FAILURE', 'autoFocus() should fail: ' + e);
|
||||
}
|
||||
|
||||
/* This is the promise chain which drives the test execution.
|
||||
|
||||
suite.getCamera
|
||||
This returns a promise which is resolved when the suite
|
||||
acquires the camera object (i.e. returns as if one
|
||||
called cameraManager.getCamera() directly). It saves
|
||||
the CameraControl reference in suite.camera and will
|
||||
automatically release it for you when the test is
|
||||
completed.
|
||||
|
||||
.then(startAutoFocusFail, suite.rejectGetCamera)
|
||||
If the getCamera promise is resolved, startAutoFocusFail
|
||||
will be called. That function attaches a handler to
|
||||
the camera test hardware to intercept the auto focus
|
||||
driver call so that we can change the behaviour to
|
||||
trigger an OnAutoFocusComplete(false) event. It then
|
||||
calls camera.autoFocus() and returns the promise for
|
||||
that camera call so that the next promise in the chain
|
||||
can block waiting for that promise to be fulfilled.
|
||||
|
||||
If the getCamera promise is rejected,
|
||||
suite.rejectGetCamera will be called. This is a helper
|
||||
handler provided by the test suite; it will log
|
||||
a get camera failure and fail the test via ok, and
|
||||
return a new promise rejecting *without* an error
|
||||
object (i.e. promise parameter is undefined). This is
|
||||
important because all reject handlers further down
|
||||
the promise chain will still be called due to the
|
||||
failure. However since we replaced the promise with
|
||||
an error object, with a promise without one, we can
|
||||
use this to identify errors that have already been
|
||||
handled.
|
||||
|
||||
.then(resolveAutoFocusFail, suite.rejectAutoFocus)
|
||||
If the suite.camera.autoFocus() promise is resolved,
|
||||
resolveAutoFocusFail will be called. That function
|
||||
simply verifies the result from the autoFocus() call.
|
||||
It should be false, given the modified behaviour we
|
||||
gave the driver. Since it doesn't return a new promise
|
||||
explicitly, it will generate a new promise which is
|
||||
already resolved (without the focused state parameter,
|
||||
will now be undefined to the next .then handler).
|
||||
|
||||
If the suite.camera.autoFocus() promise is rejected,
|
||||
we want to fail the test case again, just like when
|
||||
suite.getCamera() failed.
|
||||
|
||||
.then(startAutoFocusError)
|
||||
Assuming the first suite.camera.autoFocus() promise
|
||||
was resolved, startAutoFocusError will be called.
|
||||
That function is similar to startAutoFocusFail but
|
||||
now it throws an error in the intercepted auto focus
|
||||
driver call in order to trigger an OnUserError(kAutoFocus)
|
||||
event. It then calls and returns the promise from
|
||||
suite.camera.autoFocus().
|
||||
|
||||
.then(suite.expectedRejectAutoFocus, rejectAutoFocusError)
|
||||
Now we are expecting the previous suite.camera.autoFocus()
|
||||
promise to be rejected, which would call
|
||||
rejectAutoFocusError. This simply verifies that we
|
||||
got the error we expected.
|
||||
|
||||
If, on the other hand, it somehow succeeded, we
|
||||
let suite.expectedRejectAutoFocus handle it, which
|
||||
similar to the suite.rejectAutoFocus method, will
|
||||
fail and return an empty rejected promise.
|
||||
|
||||
Note that this method itself returns the promise chain.
|
||||
This allows the test suite to 1) capture any unhandled
|
||||
errors in the promise chain and ensure the test case
|
||||
fails as a result, and 2) perform any cleanup operations
|
||||
such as resetting low memory state, releasing the camera,
|
||||
etc, before starting the next test.
|
||||
*/
|
||||
return suite.getCamera()
|
||||
.then(startAutoFocusFail, suite.rejectGetCamera)
|
||||
.then(resolveAutoFocusFail, suite.rejectAutoFocus)
|
||||
.then(startAutoFocusError)
|
||||
.then(suite.expectedRejectAutoFocus, rejectAutoFocusError)
|
||||
});
|
||||
|
||||
CameraTest.begin("hardware", function(test) {
|
||||
function onSuccess(d) {
|
||||
cameraObj = d.camera;
|
||||
document.getElementById('viewfinder').mozSrcObject = cameraObj;
|
||||
CameraTest.next = function() {
|
||||
try {
|
||||
var t = testGenerator.next();
|
||||
test.set(t.key, t.func.bind(undefined, cameraObj));
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
end();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
suite.test('take-picture-failures', function() {
|
||||
function startTakePictureProcessError(p) {
|
||||
suite.hw.attach({
|
||||
takePicture: function() {
|
||||
suite.hw.fireTakePictureError();
|
||||
}
|
||||
};
|
||||
next();
|
||||
});
|
||||
return suite.camera.takePicture();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "getCamera() failed with: " + error);
|
||||
end();
|
||||
|
||||
function rejectTakePictureProcessError(e) {
|
||||
ok(e.name === 'NS_ERROR_FAILURE', 'takePicture() process should fail: ' + e);
|
||||
}
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
|
||||
|
||||
function startTakePictureError(p) {
|
||||
suite.hw.attach({
|
||||
takePicture: function() {
|
||||
throw SpecialPowers.Cr.NS_ERROR_FAILURE;
|
||||
}
|
||||
});
|
||||
return suite.camera.takePicture();
|
||||
}
|
||||
|
||||
function rejectTakePictureError(e) {
|
||||
ok(e.name === 'NS_ERROR_FAILURE', 'takePicture() should fail: ' + e);
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.catch(suite.rejectGetCamera)
|
||||
.then(startTakePictureProcessError)
|
||||
.then(suite.expectedRejectTakePicture, rejectTakePictureProcessError)
|
||||
.then(startTakePictureError)
|
||||
.then(suite.expectedRejectTakePicture, rejectTakePictureError)
|
||||
});
|
||||
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -17,133 +17,71 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=940424
|
|||
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var initialConfig = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
suite.test('init-failure', function() {
|
||||
var cameraManager = navigator.mozCameras;
|
||||
var whichCamera = cameraManager.getListOfCameras()[0];
|
||||
|
||||
suite.hw.attach({
|
||||
init: function() {
|
||||
throw SpecialPowers.Cr.NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
});
|
||||
|
||||
function rejectGetCamera(e) {
|
||||
ok(e.name === 'NS_ERROR_NOT_AVAILABLE', 'onError called correctly on getCamera init failure: ' + e);
|
||||
// Let the next getCamera attempt succeed
|
||||
suite.initJsHw();
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
var tests = [
|
||||
{
|
||||
name: "init-failure",
|
||||
key: "init-failure",
|
||||
func: function testInitFailure(test) {
|
||||
function onSuccess(d) {
|
||||
ok(false, "onSuccess called incorrectly");
|
||||
d.camera.release();
|
||||
test.next();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "onError called correctly on init failure");
|
||||
test.next();
|
||||
}
|
||||
info("Running test: init-failure");
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
/* This test case (init-success) *must* follow the preceeding test case
|
||||
(init-failure) in order for the desired condition to be verified */
|
||||
{
|
||||
name: "init-success",
|
||||
key: "",
|
||||
func: function(test) {
|
||||
function onSuccess(d) {
|
||||
ok(true, "onSuccess called correctly");
|
||||
d.camera.release().then(test.next);
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "onError called incorrectly: " + error);
|
||||
test.next();
|
||||
}
|
||||
info("Running test: init-success");
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError)
|
||||
}
|
||||
},
|
||||
/* Test for bug 1099390 to make sure events related to the underlying
|
||||
platform failing are generated and handled properly. */
|
||||
{
|
||||
name: "post-init-system-failure",
|
||||
key: "post-init-system-failure",
|
||||
func: function(test) {
|
||||
var gotReleasePromise = false;
|
||||
var gotCloseEvent = false;
|
||||
|
||||
function gotAll() {
|
||||
var all = gotReleasePromise && gotCloseEvent;
|
||||
if (all) {
|
||||
info("Got all expected notifications");
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
function onSuccess(d) {
|
||||
var onClosedEvent = function(e) {
|
||||
d.camera.removeEventListener('close', onClosedEvent);
|
||||
|
||||
ok(e.reason === "SystemFailure", "reason is: " + e.reason);
|
||||
ok(!gotCloseEvent, "gotCloseEvent was " + gotCloseEvent);
|
||||
gotCloseEvent = true;
|
||||
if (gotAll()) {
|
||||
test.next();
|
||||
}
|
||||
|
||||
d.camera.release().then(
|
||||
function resolve(e) {
|
||||
ok(true, "release() promise resolved");
|
||||
ok(!gotReleasePromise, "gotReleasePromise was " + gotReleasePromise);
|
||||
gotReleasePromise = true;
|
||||
if (gotAll()) {
|
||||
test.next();
|
||||
}
|
||||
},
|
||||
function reject(e) {
|
||||
ok(false, "release() promise unexpected rejected: " + e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
d.camera.addEventListener('close', onClosedEvent);
|
||||
}
|
||||
|
||||
function onError(error) {
|
||||
ok(false, "onError called incorrectly: " + error);
|
||||
test.next();
|
||||
}
|
||||
|
||||
info("Running test: post-init-system-failure");
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError)
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var testGenerator = function() {
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
yield tests[i];
|
||||
function resolveGetCamera(p) {
|
||||
ok(true, 'onSuccess called correctly for second getCamera request');
|
||||
}
|
||||
}();
|
||||
|
||||
CameraTest.begin("hardware", function(test) {
|
||||
CameraTest.next = function() {
|
||||
try {
|
||||
var t = testGenerator.next();
|
||||
test.set(t.key, t.func.bind(undefined, CameraTest));
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
CameraTest.end();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
CameraTest.next();
|
||||
return cameraManager.getCamera(whichCamera)
|
||||
.then(suite.expectedRejectGetCamera, rejectGetCamera)
|
||||
.then(suite.getCamera)
|
||||
.then(resolveGetCamera, suite.rejectGetCamera)
|
||||
});
|
||||
|
||||
/* Test for bug 1099390 to make sure events related to the underlying
|
||||
platform failing are generated and handled properly. */
|
||||
suite.test('post-init-system-failure', function() {
|
||||
function triggerSystemFailure(p) {
|
||||
var sync = new Promise(function(resolve, reject) {
|
||||
function onClosedEvent(e) {
|
||||
suite.camera.removeEventListener('close', onClosedEvent);
|
||||
ok(e.reason === 'SystemFailure', 'reason is: ' + e.reason);
|
||||
resolve();
|
||||
}
|
||||
suite.camera.addEventListener('close', onClosedEvent);
|
||||
});
|
||||
|
||||
suite.hw.fireSystemError();
|
||||
return sync;
|
||||
}
|
||||
|
||||
function releaseCamera(p) {
|
||||
var camera = suite.camera;
|
||||
suite.camera = null;
|
||||
return camera.release();
|
||||
}
|
||||
|
||||
function releasedCamera(p) {
|
||||
ok(true, 'camera released after system failure');
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(triggerSystemFailure, suite.rejectGetCamera)
|
||||
.then(releaseCamera)
|
||||
.then(releasedCamera, suite.rejectRelease);
|
||||
});
|
||||
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -80,6 +80,10 @@ DocumentRendererChild::RenderDocument(nsIDOMWindow *window,
|
|||
IntSize(renderSize.width, renderSize.height),
|
||||
4 * renderSize.width,
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
if (!dt) {
|
||||
gfxWarning() << "DocumentRendererChild::RenderDocument failed to Factory::CreateDrawTargetForData";
|
||||
return false;
|
||||
}
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(dt);
|
||||
ctx->SetMatrix(mozilla::gfx::ThebesMatrix(transform));
|
||||
|
||||
|
|
|
@ -98,7 +98,6 @@ EventListenerManager::EventListenerManager(EventTarget* aTarget)
|
|||
, mMayHaveCapturingListeners(false)
|
||||
, mMayHaveSystemGroupListeners(false)
|
||||
, mMayHaveTouchEventListener(false)
|
||||
, mMayHaveScrollWheelEventListener(false)
|
||||
, mMayHaveMouseEnterLeaveEventListener(false)
|
||||
, mMayHavePointerEnterLeaveEventListener(false)
|
||||
, mClearingListeners(false)
|
||||
|
@ -340,16 +339,6 @@ EventListenerManager::AddEventListenerInternal(
|
|||
if (window && !aFlags.mInSystemGroup) {
|
||||
window->SetHasTouchEventListeners();
|
||||
}
|
||||
} else if (aTypeAtom == nsGkAtoms::onwheel ||
|
||||
aTypeAtom == nsGkAtoms::onDOMMouseScroll ||
|
||||
aTypeAtom == nsHtml5Atoms::onmousewheel) {
|
||||
mMayHaveScrollWheelEventListener = true;
|
||||
nsPIDOMWindow* window = GetInnerWindowForTarget();
|
||||
// we don't want touchevent listeners added by scrollbars to flip this flag
|
||||
// so we ignore listeners created with system event flag
|
||||
if (window && !aFlags.mInSystemGroup) {
|
||||
window->SetHasScrollWheelEventListeners();
|
||||
}
|
||||
} else if (aType >= NS_POINTER_EVENT_START && aType <= NS_POINTER_LOST_CAPTURE) {
|
||||
nsPIDOMWindow* window = GetInnerWindowForTarget();
|
||||
if (aTypeAtom == nsGkAtoms::onpointerenter ||
|
||||
|
|
|
@ -394,12 +394,6 @@ public:
|
|||
*/
|
||||
bool MayHaveTouchEventListener() { return mMayHaveTouchEventListener; }
|
||||
|
||||
/**
|
||||
* Returns true if there may be a scroll wheel listener registered,
|
||||
* false if there definitely isn't.
|
||||
*/
|
||||
bool MayHaveScrollWheelEventListener() { return mMayHaveScrollWheelEventListener; }
|
||||
|
||||
bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; }
|
||||
bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; }
|
||||
|
||||
|
@ -550,7 +544,6 @@ protected:
|
|||
uint32_t mMayHaveCapturingListeners : 1;
|
||||
uint32_t mMayHaveSystemGroupListeners : 1;
|
||||
uint32_t mMayHaveTouchEventListener : 1;
|
||||
uint32_t mMayHaveScrollWheelEventListener : 1;
|
||||
uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
|
||||
uint32_t mMayHavePointerEnterLeaveEventListener : 1;
|
||||
uint32_t mClearingListeners : 1;
|
||||
|
|
|
@ -60,8 +60,6 @@ public:
|
|||
mType = aType;
|
||||
}
|
||||
|
||||
~FMRadioRequest() { }
|
||||
|
||||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
|
@ -97,6 +95,9 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
~FMRadioRequest() { }
|
||||
|
||||
private:
|
||||
FMRadioRequestArgs::Type mType;
|
||||
nsWeakPtr mFMRadio;
|
||||
|
|
|
@ -238,6 +238,9 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
~ReadAirplaneModeSettingTask() {}
|
||||
|
||||
private:
|
||||
nsRefPtr<FMRadioReplyRunnable> mPendingRequest;
|
||||
};
|
||||
|
|
|
@ -159,7 +159,6 @@ class FMRadioService MOZ_FINAL : public IFMRadioService
|
|||
|
||||
public:
|
||||
static FMRadioService* Singleton();
|
||||
virtual ~FMRadioService();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
@ -201,6 +200,7 @@ public:
|
|||
|
||||
protected:
|
||||
FMRadioService();
|
||||
virtual ~FMRadioService();
|
||||
|
||||
private:
|
||||
int32_t RoundFrequency(double aFrequencyInMHz);
|
||||
|
|
|
@ -51,6 +51,7 @@ class nsIPrincipal;
|
|||
|
||||
#ifdef XP_WIN
|
||||
#include "WindowsLocationProvider.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#endif
|
||||
|
||||
// Some limit to the number of get or watch geolocation requests
|
||||
|
@ -815,7 +816,8 @@ nsresult nsGeolocationService::Init()
|
|||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (Preferences::GetBool("geo.provider.ms-windows-location", false)) {
|
||||
if (Preferences::GetBool("geo.provider.ms-windows-location", false) &&
|
||||
IsWin8OrLater()) {
|
||||
mProvider = new WindowsLocationProvider();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -44,7 +44,7 @@ void
|
|||
HTMLPictureElement::RemoveChildAt(uint32_t aIndex, bool aNotify)
|
||||
{
|
||||
// Find all img siblings after this <source> to notify them of its demise
|
||||
nsCOMPtr<nsINode> child = GetChildAt(aIndex);
|
||||
nsCOMPtr<nsIContent> child = GetChildAt(aIndex);
|
||||
nsCOMPtr<nsIContent> nextSibling;
|
||||
if (child && child->IsHTMLElement(nsGkAtoms::source)) {
|
||||
nextSibling = child->GetNextSibling();
|
||||
|
|
|
@ -80,7 +80,7 @@ HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
{
|
||||
// If we are associated with a <picture> with a valid <img>, notify it of
|
||||
// responsive parameter changes
|
||||
nsINode *parent = nsINode::GetParentNode();
|
||||
Element *parent = nsINode::GetParentElement();
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::srcset ||
|
||||
aName == nsGkAtoms::sizes ||
|
||||
|
@ -89,7 +89,7 @@ HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
parent && parent->IsHTMLElement(nsGkAtoms::picture)) {
|
||||
nsString strVal = aValue ? aValue->GetStringValue() : EmptyString();
|
||||
// Find all img siblings after this <source> and notify them of the change
|
||||
nsCOMPtr<nsINode> sibling = AsContent();
|
||||
nsCOMPtr<nsIContent> sibling = AsContent();
|
||||
while ( (sibling = sibling->GetNextSibling()) ) {
|
||||
if (sibling->IsHTMLElement(nsGkAtoms::img)) {
|
||||
HTMLImageElement *img = static_cast<HTMLImageElement*>(sibling.get());
|
||||
|
@ -149,7 +149,7 @@ HTMLSourceElement::BindToTree(nsIDocument *aDocument,
|
|||
media->NotifyAddedSource();
|
||||
} else if (aParent && aParent->IsHTMLElement(nsGkAtoms::picture)) {
|
||||
// Find any img siblings after this <source> and notify them
|
||||
nsCOMPtr<nsINode> sibling = AsContent();
|
||||
nsCOMPtr<nsIContent> sibling = AsContent();
|
||||
while ( (sibling = sibling->GetNextSibling()) ) {
|
||||
if (sibling->IsHTMLElement(nsGkAtoms::img)) {
|
||||
HTMLImageElement *img = static_cast<HTMLImageElement*>(sibling.get());
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
default-preferences pref(dom.forms.number,true)
|
||||
skip-if(B2G) needs-focus == input-load.html input-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G) needs-focus == input-create.html input-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G) needs-focus == input-number.html input-number-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G) needs-focus == button-load.html button-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G) needs-focus == button-create.html button-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G) needs-focus == textarea-load.html textarea-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G) needs-focus == textarea-create.html textarea-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G) needs-focus == select-load.html select-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G) needs-focus == select-create.html select-ref.html # B2G timed out waiting for reftest-wait to be removed
|
||||
skip-if(B2G||Mulet) needs-focus == input-load.html input-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == input-create.html input-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == input-number.html input-number-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == button-load.html button-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == button-create.html button-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == textarea-load.html textarea-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == textarea-create.html textarea-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == select-load.html select-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == select-create.html select-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
needs-focus == autofocus-after-load.html autofocus-after-load-ref.html
|
||||
fails-if(B2G) needs-focus == autofocus-leaves-iframe.html autofocus-leaves-iframe-ref.html # B2G focus difference between test and reference
|
||||
skip-if(B2G) needs-focus == autofocus-after-body-focus.html autofocus-after-body-focus-ref.html # bug 773482
|
||||
fails-if(B2G||Mulet) needs-focus == autofocus-leaves-iframe.html autofocus-leaves-iframe-ref.html # B2G focus difference between test and reference # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) needs-focus == autofocus-after-body-focus.html autofocus-after-body-focus-ref.html # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::jsipc;
|
||||
|
@ -15,7 +16,9 @@ using namespace mozilla::jsipc;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(ContentBridgeParent, nsIContentParent)
|
||||
NS_IMPL_ISUPPORTS(ContentBridgeParent,
|
||||
nsIContentParent,
|
||||
nsIObserver)
|
||||
|
||||
ContentBridgeParent::ContentBridgeParent(Transport* aTransport)
|
||||
: mTransport(aTransport)
|
||||
|
@ -29,6 +32,10 @@ ContentBridgeParent::~ContentBridgeParent()
|
|||
void
|
||||
ContentBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->RemoveObserver(this, "content-child-shutdown");
|
||||
}
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &ContentBridgeParent::DeferredDestroy));
|
||||
|
@ -49,6 +56,11 @@ ContentBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
|
|||
DebugOnly<bool> ok = bridge->Open(aTransport, handle, XRE_GetIOMessageLoop());
|
||||
MOZ_ASSERT(ok);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->AddObserver(bridge, "content-child-shutdown", false);
|
||||
}
|
||||
|
||||
// Initialize the message manager (and load delayed scripts) now that we
|
||||
// have established communications with the child.
|
||||
bridge->mMessageManager->InitWithCallback(bridge);
|
||||
|
@ -167,5 +179,16 @@ ContentBridgeParent::GetCPOWManager()
|
|||
return CPOWManagerFor(SendPJavaScriptConstructor());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentBridgeParent::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, "content-child-shutdown")) {
|
||||
Close();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -10,17 +10,20 @@
|
|||
#include "mozilla/dom/PContentBridgeParent.h"
|
||||
#include "mozilla/dom/nsIContentParent.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ContentBridgeParent : public PContentBridgeParent
|
||||
, public nsIContentParent
|
||||
, public nsIObserver
|
||||
{
|
||||
public:
|
||||
explicit ContentBridgeParent(Transport* aTransport);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
void DeferredDestroy();
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
virtual nsresult Find(const nsACString& aType,
|
||||
nsTArray<nsRefPtr<MuxerOperation>>& aOperations) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~MuxerOperation() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "MediaTaskQueue.h"
|
||||
#include "mp4_demuxer/DecoderData.h"
|
||||
#include "mp4_demuxer/AnnexB.h"
|
||||
#include "mp4_demuxer/H264.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
@ -205,6 +206,14 @@ AVCCMediaDataDecoder::CreateDecoderAndInit(mp4_demuxer::MP4Sample* aSample)
|
|||
if (!mp4_demuxer::AnnexB::HasSPS(extra_data)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
mp4_demuxer::SPSData spsdata;
|
||||
if (mp4_demuxer::H264::DecodeSPSFromExtraData(extra_data, spsdata) &&
|
||||
spsdata.pic_width > 0 && spsdata.pic_height > 0) {
|
||||
mCurrentConfig.image_width = spsdata.pic_width;
|
||||
mCurrentConfig.image_height = spsdata.pic_height;
|
||||
mCurrentConfig.display_width = spsdata.display_width;
|
||||
mCurrentConfig.display_height = spsdata.display_height;
|
||||
}
|
||||
mCurrentConfig.extra_data = extra_data;
|
||||
|
||||
nsresult rv = CreateDecoder();
|
||||
|
|
|
@ -149,9 +149,10 @@ PlatformDecoderModule::CreatePDM()
|
|||
#endif
|
||||
#ifdef MOZ_FFMPEG
|
||||
if (sFFmpegDecoderEnabled) {
|
||||
nsRefPtr<PlatformDecoderModule> m(FFmpegRuntimeLinker::CreateDecoderModule());
|
||||
nsRefPtr<PlatformDecoderModule> m = FFmpegRuntimeLinker::CreateDecoderModule();
|
||||
if (m) {
|
||||
return m.forget();
|
||||
nsRefPtr<PlatformDecoderModule> m2(new AVCCDecoderModule(m));
|
||||
return m2.forget();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "prlog.h"
|
||||
#include "VideoUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* GetAppleMediaLog();
|
||||
|
@ -35,10 +36,13 @@ AppleVDADecoder::AppleVDADecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
|
|||
FlushableMediaTaskQueue* aVideoTaskQueue,
|
||||
MediaDataDecoderCallback* aCallback,
|
||||
layers::ImageContainer* aImageContainer)
|
||||
: mConfig(aConfig)
|
||||
, mTaskQueue(aVideoTaskQueue)
|
||||
: mTaskQueue(aVideoTaskQueue)
|
||||
, mCallback(aCallback)
|
||||
, mImageContainer(aImageContainer)
|
||||
, mPictureWidth(aConfig.image_width)
|
||||
, mPictureHeight(aConfig.image_height)
|
||||
, mDisplayWidth(aConfig.display_width)
|
||||
, mDisplayHeight(aConfig.display_height)
|
||||
, mDecoder(nullptr)
|
||||
, mIs106(!nsCocoaFeatures::OnLionOrLater())
|
||||
{
|
||||
|
@ -46,26 +50,24 @@ AppleVDADecoder::AppleVDADecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
|
|||
// TODO: Verify aConfig.mime_type.
|
||||
|
||||
// Retrieve video dimensions from H264 SPS NAL.
|
||||
mPictureWidth = mConfig.image_width;
|
||||
mPictureHeight = mConfig.image_height;
|
||||
mPictureWidth = aConfig.image_width;
|
||||
mExtraData = aConfig.extra_data;
|
||||
mMaxRefFrames = 4;
|
||||
mp4_demuxer::SPSData spsdata;
|
||||
if (mp4_demuxer::H264::DecodeSPSFromExtraData(mConfig.extra_data, spsdata) &&
|
||||
spsdata.pic_width && spsdata.pic_height) {
|
||||
mPictureWidth = spsdata.pic_width;
|
||||
mPictureHeight = spsdata.pic_height;
|
||||
if (mp4_demuxer::H264::DecodeSPSFromExtraData(mExtraData, spsdata)) {
|
||||
// max_num_ref_frames determines the size of the sliding window
|
||||
// we need to queue that many frames in order to guarantee proper
|
||||
// pts frames ordering. Use a minimum of 4 to ensure proper playback of
|
||||
// non compliant videos.
|
||||
mMaxRefFrames =
|
||||
(spsdata.max_num_ref_frames + 1) > mMaxRefFrames ?
|
||||
spsdata.max_num_ref_frames + 1 : mMaxRefFrames;
|
||||
std::min(std::max(mMaxRefFrames, spsdata.max_num_ref_frames + 1), 16u);
|
||||
}
|
||||
|
||||
LOG("Creating AppleVDADecoder for %dx%d h.264 video",
|
||||
LOG("Creating AppleVDADecoder for %dx%d (%dx%d) h.264 video",
|
||||
mPictureWidth,
|
||||
mPictureHeight
|
||||
mPictureHeight,
|
||||
mDisplayWidth,
|
||||
mDisplayHeight
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -257,12 +259,12 @@ AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
|
|||
nsRefPtr<MacIOSurface> macSurface = new MacIOSurface(surface);
|
||||
// Bounds.
|
||||
VideoInfo info;
|
||||
info.mDisplay = nsIntSize(mConfig.display_width, mConfig.display_height);
|
||||
info.mDisplay = nsIntSize(mDisplayWidth, mDisplayHeight);
|
||||
info.mHasVideo = true;
|
||||
gfx::IntRect visible = gfx::IntRect(0,
|
||||
0,
|
||||
mConfig.display_width,
|
||||
mConfig.display_height);
|
||||
mPictureWidth,
|
||||
mPictureHeight);
|
||||
|
||||
nsRefPtr<layers::Image> image =
|
||||
mImageContainer->CreateImage(ImageFormat::MAC_IOSURFACE);
|
||||
|
@ -410,8 +412,8 @@ AppleVDADecoder::InitializeSession()
|
|||
CFDictionaryRef
|
||||
AppleVDADecoder::CreateDecoderSpecification()
|
||||
{
|
||||
const uint8_t* extradata = mConfig.extra_data->Elements();
|
||||
int extrasize = mConfig.extra_data->Length();
|
||||
const uint8_t* extradata = mExtraData->Elements();
|
||||
int extrasize = mExtraData->Length();
|
||||
|
||||
OSType format = 'avc1';
|
||||
AutoCFRelease<CFNumberRef> avc_width =
|
||||
|
|
|
@ -89,13 +89,15 @@ public:
|
|||
void ClearReorderedFrames();
|
||||
CFDictionaryRef CreateOutputConfiguration();
|
||||
|
||||
const mp4_demuxer::VideoDecoderConfig& mConfig;
|
||||
nsRefPtr<mp4_demuxer::ByteBuffer> mExtraData;
|
||||
nsRefPtr<FlushableMediaTaskQueue> mTaskQueue;
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
nsRefPtr<layers::ImageContainer> mImageContainer;
|
||||
ReorderQueue mReorderQueue;
|
||||
uint32_t mPictureWidth;
|
||||
uint32_t mPictureHeight;
|
||||
uint32_t mDisplayWidth;
|
||||
uint32_t mDisplayHeight;
|
||||
uint32_t mMaxRefFrames;
|
||||
|
||||
private:
|
||||
|
|
|
@ -46,8 +46,8 @@ AppleVTDecoder::AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
|
|||
MOZ_COUNT_CTOR(AppleVTDecoder);
|
||||
// TODO: Verify aConfig.mime_type.
|
||||
LOG("Creating AppleVTDecoder for %dx%d h.264 video",
|
||||
mConfig.image_width,
|
||||
mConfig.image_height
|
||||
mDisplayWidth,
|
||||
mDisplayHeight
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ AppleVTDecoder::InitializeSession()
|
|||
|
||||
#ifdef LOG_MEDIA_SHA1
|
||||
SHA1Sum avc_hash;
|
||||
avc_hash.update(mConfig.extra_data->Elements(), mConfig.extra_data->Length());
|
||||
avc_hash.update(mExtraData->Elements(),mExtraData->Length());
|
||||
uint8_t digest_buf[SHA1Sum::kHashSize];
|
||||
avc_hash.finish(digest_buf);
|
||||
nsAutoCString avc_digest;
|
||||
|
@ -270,7 +270,7 @@ AppleVTDecoder::InitializeSession()
|
|||
avc_digest.AppendPrintf("%02x", digest_buf[i]);
|
||||
}
|
||||
LOG("AVCDecoderConfig %ld bytes sha1 %s",
|
||||
mConfig.extra_data->Length(), avc_digest.get());
|
||||
mExtraData->Length(), avc_digest.get());
|
||||
#endif // LOG_MEDIA_SHA1
|
||||
|
||||
AutoCFRelease<CFDictionaryRef> extensions = CreateDecoderExtensions();
|
||||
|
@ -329,8 +329,8 @@ AppleVTDecoder::CreateDecoderExtensions()
|
|||
{
|
||||
AutoCFRelease<CFDataRef> avc_data =
|
||||
CFDataCreate(kCFAllocatorDefault,
|
||||
mConfig.extra_data->Elements(),
|
||||
mConfig.extra_data->Length());
|
||||
mExtraData->Elements(),
|
||||
mExtraData->Length());
|
||||
|
||||
const void* atomsKey[] = { CFSTR("avcC") };
|
||||
const void* atomsValue[] = { avc_data };
|
||||
|
|
|
@ -63,6 +63,11 @@ public:
|
|||
return FFmpegH264Decoder<V>::GetCodecId(aMimeType) != AV_CODEC_ID_NONE;
|
||||
}
|
||||
|
||||
virtual bool DecoderNeedsAVCC(const mp4_demuxer::VideoDecoderConfig& aConfig) MOZ_OVERRIDE
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "ImageContainer.h"
|
||||
|
||||
#include "mp4_demuxer/mp4_demuxer.h"
|
||||
#include "mp4_demuxer/AnnexB.h"
|
||||
|
||||
#include "FFmpegH264Decoder.h"
|
||||
|
||||
|
@ -31,8 +30,11 @@ FFmpegH264Decoder<LIBAV_VER>::FFmpegH264Decoder(
|
|||
: FFmpegDataDecoder(aTaskQueue, GetCodecId(aConfig.mime_type))
|
||||
, mCallback(aCallback)
|
||||
, mImageContainer(aImageContainer)
|
||||
, mDisplayWidth(aConfig.display_width)
|
||||
, mDisplayHeight(aConfig.display_height)
|
||||
{
|
||||
MOZ_COUNT_CTOR(FFmpegH264Decoder);
|
||||
mExtraData = aConfig.extra_data;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -53,12 +55,6 @@ FFmpegH264Decoder<LIBAV_VER>::DoDecodeFrame(mp4_demuxer::MP4Sample* aSample)
|
|||
AVPacket packet;
|
||||
av_init_packet(&packet);
|
||||
|
||||
if (!mp4_demuxer::AnnexB::ConvertSampleToAnnexB(aSample)) {
|
||||
NS_WARNING("FFmpeg h264 decoder failed to convert sample to Annex B.");
|
||||
mCallback->Error();
|
||||
return DecodeResult::DECODE_ERROR;
|
||||
}
|
||||
|
||||
if (!aSample->Pad(FF_INPUT_BUFFER_PADDING_SIZE)) {
|
||||
NS_WARNING("FFmpeg h264 decoder failed to allocate sample.");
|
||||
mCallback->Error();
|
||||
|
@ -91,7 +87,7 @@ FFmpegH264Decoder<LIBAV_VER>::DoDecodeFrame(mp4_demuxer::MP4Sample* aSample)
|
|||
// If we've decoded a frame then we need to output it
|
||||
if (decoded) {
|
||||
VideoInfo info;
|
||||
info.mDisplay = nsIntSize(mCodecContext->width, mCodecContext->height);
|
||||
info.mDisplay = nsIntSize(mDisplayWidth, mDisplayHeight);
|
||||
info.mStereoMode = StereoMode::MONO;
|
||||
info.mHasVideo = true;
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ private:
|
|||
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
nsRefPtr<ImageContainer> mImageContainer;
|
||||
uint32_t mDisplayWidth;
|
||||
uint32_t mDisplayHeight;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -275,10 +275,12 @@ private:
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SignalObject)
|
||||
|
||||
SignalObject(const char* aName);
|
||||
~SignalObject();
|
||||
void Wait();
|
||||
void Signal();
|
||||
|
||||
protected:
|
||||
~SignalObject();
|
||||
|
||||
private:
|
||||
// Forbidden
|
||||
SignalObject() = delete;
|
||||
|
|
|
@ -278,7 +278,6 @@ private:
|
|||
*/
|
||||
class OMXVideoEncoder MOZ_FINAL : public OMXCodecWrapper
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OMXVideoEncoder)
|
||||
public:
|
||||
// Types of output blob format.
|
||||
enum BlobFormat {
|
||||
|
|
|
@ -48,6 +48,7 @@ RtspOmxReader::Seek(int64_t aTime, int64_t aEndTime)
|
|||
// seek operation. The function will clear the |mVideoQueue| and |mAudioQueue|
|
||||
// that store the decoded data and also call the |DecodeToTarget| to pass
|
||||
// the seek time to OMX a/v decoders.
|
||||
mEnsureActiveFromSeek = true;
|
||||
return MediaOmxReader::Seek(aTime, aEndTime);
|
||||
}
|
||||
|
||||
|
@ -71,9 +72,13 @@ void RtspOmxReader::EnsureActive() {
|
|||
if (mRtspResource) {
|
||||
nsIStreamingProtocolController* controller =
|
||||
mRtspResource->GetMediaStreamController();
|
||||
if (controller) {
|
||||
// We do not have to call Play if the EnsureActive request is from Seek
|
||||
// operation because RTSP connection must already be established before
|
||||
// performing Seek.
|
||||
if (controller && !mEnsureActiveFromSeek) {
|
||||
controller->Play();
|
||||
}
|
||||
mEnsureActiveFromSeek = false;
|
||||
mRtspResource->SetSuspend(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,9 @@ protected:
|
|||
|
||||
public:
|
||||
RtspOmxReader(AbstractMediaDecoder* aDecoder)
|
||||
: MediaOmxReader(aDecoder) {
|
||||
: MediaOmxReader(aDecoder)
|
||||
, mEnsureActiveFromSeek(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(RtspOmxReader);
|
||||
NS_ASSERTION(mDecoder, "RtspOmxReader mDecoder is null.");
|
||||
NS_ASSERTION(mDecoder->GetResource(),
|
||||
|
@ -73,6 +75,8 @@ private:
|
|||
// holds the MediaDecoderStateMachine and RtspMediaResource.
|
||||
// And MediaDecoderStateMachine holds this RtspOmxReader.
|
||||
RtspMediaResource* mRtspResource;
|
||||
|
||||
bool mEnsureActiveFromSeek;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -90,7 +90,6 @@ DIRS += [
|
|||
'indexedDB',
|
||||
'system',
|
||||
'ipc',
|
||||
'identity',
|
||||
'workers',
|
||||
'camera',
|
||||
'audiochannel',
|
||||
|
@ -142,6 +141,7 @@ if CONFIG['MOZ_SECUREELEMENT']:
|
|||
if CONFIG['MOZ_B2G']:
|
||||
DIRS += [
|
||||
'downloads',
|
||||
'identity',
|
||||
'mobileid',
|
||||
'engineeringmode'
|
||||
]
|
||||
|
|
|
@ -7,25 +7,26 @@
|
|||
/* Copyright © 2013 Deutsche Telekom, Inc. */
|
||||
|
||||
#include "MozNDEFRecord.h"
|
||||
#include "js/StructuredClone.h"
|
||||
#include "mozilla/dom/MozNDEFRecordBinding.h"
|
||||
#include "mozilla/HoldDropJSObjects.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(MozNDEFRecord)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MozNDEFRecord)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->DropData();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MozNDEFRecord)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
@ -69,8 +70,7 @@ MozNDEFRecord::DropData()
|
|||
* See section 3.3 THE NDEF Specification Test Requirements,
|
||||
* NDEF specification 1.0
|
||||
*/
|
||||
/* static */
|
||||
bool
|
||||
/* static */ bool
|
||||
MozNDEFRecord::ValidateTNF(const MozNDEFRecordOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
|
@ -100,66 +100,285 @@ MozNDEFRecord::ValidateTNF(const MozNDEFRecordOptions& aOptions,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<MozNDEFRecord>
|
||||
/* static */ already_AddRefed<MozNDEFRecord>
|
||||
MozNDEFRecord::Constructor(const GlobalObject& aGlobal,
|
||||
const MozNDEFRecordOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!win) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ValidateTNF(aOptions, aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<MozNDEFRecord> ndefrecord = new MozNDEFRecord(aGlobal.Context(),
|
||||
win, aOptions);
|
||||
if (!ndefrecord) {
|
||||
nsCOMPtr<nsISupports> parent = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!parent) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
return ndefrecord.forget();
|
||||
|
||||
JSContext* context = aGlobal.Context();
|
||||
nsRefPtr<MozNDEFRecord> ndefRecord = new MozNDEFRecord(parent, aOptions.mTnf);
|
||||
ndefRecord->InitType(context, aOptions.mType);
|
||||
ndefRecord->InitId(context, aOptions.mId);
|
||||
ndefRecord->InitPayload(context, aOptions.mPayload);
|
||||
|
||||
return ndefRecord.forget();
|
||||
}
|
||||
|
||||
MozNDEFRecord::MozNDEFRecord(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
const MozNDEFRecordOptions& aOptions)
|
||||
/* static */ already_AddRefed<MozNDEFRecord>
|
||||
MozNDEFRecord::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aUri,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
mWindow = aWindow; // For GetParentObject()
|
||||
|
||||
mTnf = aOptions.mTnf;
|
||||
mSize = 3; // 1(flags) + 1(type_length) + 1(payload_length)
|
||||
|
||||
if (aOptions.mType.WasPassed()) {
|
||||
const Uint8Array& type = aOptions.mType.Value();
|
||||
type.ComputeLengthAndData();
|
||||
mType = Uint8Array::Create(aCx, this, type.Length(), type.Data());
|
||||
mSize += type.Length();
|
||||
if (aUri.IsVoid()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mId.WasPassed()) {
|
||||
const Uint8Array& id = aOptions.mId.Value();
|
||||
id.ComputeLengthAndData();
|
||||
mId = Uint8Array::Create(aCx, this, id.Length(), id.Data());
|
||||
mSize += 1 /* id_length */ + id.Length();
|
||||
nsCOMPtr<nsISupports> parent = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!parent) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mPayload.WasPassed()) {
|
||||
const Uint8Array& payload = aOptions.mPayload.Value();
|
||||
payload.ComputeLengthAndData();
|
||||
mPayload = Uint8Array::Create(aCx, this, payload.Length(), payload.Data());
|
||||
if (payload.Length() > 0xff) {
|
||||
mSize += 3;
|
||||
}
|
||||
mSize += payload.Length();
|
||||
}
|
||||
nsRefPtr<MozNDEFRecord> ndefRecord = new MozNDEFRecord(parent, TNF::Well_known);
|
||||
ndefRecord->InitType(aGlobal.Context(), RTD::U);
|
||||
ndefRecord->InitPayload(aGlobal.Context(), aUri);
|
||||
return ndefRecord.forget();
|
||||
}
|
||||
|
||||
MozNDEFRecord::MozNDEFRecord(nsISupports* aParent, TNF aTnf)
|
||||
: mParent(aParent) // For GetParentObject()
|
||||
, mTnf(aTnf)
|
||||
, mSize(3) // 1(flags) + 1(type_length) + 1(payload_length)
|
||||
{
|
||||
HoldData();
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::GetAsURI(nsAString& aRetVal)
|
||||
{
|
||||
aRetVal.SetIsVoid(true);
|
||||
if (mTnf != TNF::Well_known) {
|
||||
return;
|
||||
}
|
||||
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
uint8_t* typeData = JS_GetUint8ArrayData(mType, nogc);
|
||||
const char* uVal = RTDValues::strings[static_cast<uint32_t>(RTD::U)].value;
|
||||
if (typeData[0] != uVal[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t payloadLen;
|
||||
uint8_t* payloadData;
|
||||
js::GetUint8ArrayLengthAndData(mPayload, &payloadLen, &payloadData);
|
||||
uint8_t id = payloadData[0];
|
||||
if (id >= static_cast<uint8_t>(WellKnownURIPrefix::EndGuard_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace mozilla::dom::WellKnownURIPrefixValues;
|
||||
aRetVal.AssignASCII(strings[id].value);
|
||||
aRetVal.Append(NS_ConvertUTF8toUTF16(
|
||||
nsDependentCSubstring(reinterpret_cast<char*>(&payloadData[1]), payloadLen - 1)));
|
||||
}
|
||||
|
||||
bool
|
||||
MozNDEFRecord::WriteStructuredClone(JSContext* aCx, JSStructuredCloneWriter* aWriter) const
|
||||
{
|
||||
uint8_t* dummy;
|
||||
uint32_t typeLen = 0, idLen = 0, payloadLen = 0;
|
||||
if (mType) {
|
||||
js::GetUint8ArrayLengthAndData(mType, &typeLen, &dummy);
|
||||
}
|
||||
|
||||
if (mId) {
|
||||
js::GetUint8ArrayLengthAndData(mId, &idLen, &dummy);
|
||||
}
|
||||
|
||||
if (mPayload) {
|
||||
js::GetUint8ArrayLengthAndData(mPayload, &payloadLen, &dummy);
|
||||
}
|
||||
|
||||
return JS_WriteUint32Pair(aWriter, static_cast<uint32_t>(mTnf), typeLen) &&
|
||||
JS_WriteUint32Pair(aWriter, idLen, payloadLen) &&
|
||||
WriteUint8Array(aCx, aWriter, mType, typeLen) &&
|
||||
WriteUint8Array(aCx, aWriter, mId, idLen) &&
|
||||
WriteUint8Array(aCx, aWriter, mPayload, payloadLen);
|
||||
}
|
||||
|
||||
bool
|
||||
MozNDEFRecord::ReadStructuredClone(JSContext* aCx, JSStructuredCloneReader* aReader)
|
||||
{
|
||||
uint32_t tnf, typeLen, idLen, payloadLen;
|
||||
|
||||
if (!JS_ReadUint32Pair(aReader, &tnf, &typeLen) ||
|
||||
!JS_ReadUint32Pair(aReader, &idLen, &payloadLen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mTnf = static_cast<TNF>(tnf);
|
||||
|
||||
if (typeLen) {
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!JS_ReadTypedArray(aReader, &value)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(value.isObject());
|
||||
InitType(aCx, value.toObject(), typeLen);
|
||||
}
|
||||
|
||||
if (idLen) {
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!JS_ReadTypedArray(aReader, &value)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(value.isObject());
|
||||
InitId(aCx, value.toObject(), idLen);
|
||||
}
|
||||
|
||||
if (payloadLen) {
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!JS_ReadTypedArray(aReader, &value)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(value.isObject());
|
||||
InitPayload(aCx, value.toObject(), payloadLen);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::InitType(JSContext* aCx, const Optional<Nullable<Uint8Array>>& aType)
|
||||
{
|
||||
if (!aType.WasPassed() || aType.Value().IsNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Uint8Array& type = aType.Value().Value();
|
||||
type.ComputeLengthAndData();
|
||||
mType = Uint8Array::Create(aCx, this, type.Length(), type.Data());
|
||||
IncSize(type.Length());
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::InitType(JSContext* aCx, RTD rtd)
|
||||
{
|
||||
EnumEntry rtdType = RTDValues::strings[static_cast<uint32_t>(rtd)];
|
||||
mType = Uint8Array::Create(aCx, rtdType.length,
|
||||
reinterpret_cast<const uint8_t*>(rtdType.value));
|
||||
IncSize(rtdType.length);
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::InitType(JSContext* aCx, JSObject& aType, uint32_t aLen)
|
||||
{
|
||||
mType = &aType;
|
||||
IncSize(aLen);
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::InitId(JSContext* aCx, const Optional<Nullable<Uint8Array>>& aId)
|
||||
{
|
||||
if (!aId.WasPassed() || aId.Value().IsNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Uint8Array& id = aId.Value().Value();
|
||||
id.ComputeLengthAndData();
|
||||
mId = Uint8Array::Create(aCx, this, id.Length(), id.Data());
|
||||
IncSize(1 /* id_length */ + id.Length());
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::InitId(JSContext* aCx, JSObject& aId, uint32_t aLen)
|
||||
{
|
||||
mId = &aId;
|
||||
IncSize(1 /* id_length */ + aLen);
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::InitPayload(JSContext* aCx, const Optional<Nullable<Uint8Array>>& aPayload)
|
||||
{
|
||||
if (!aPayload.WasPassed() || aPayload.Value().IsNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Uint8Array& payload = aPayload.Value().Value();
|
||||
payload.ComputeLengthAndData();
|
||||
mPayload = Uint8Array::Create(aCx, this, payload.Length(), payload.Data());
|
||||
IncSizeForPayload(payload.Length());
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::InitPayload(JSContext* aCx, const nsAString& aUri)
|
||||
{
|
||||
using namespace mozilla::dom::WellKnownURIPrefixValues;
|
||||
|
||||
nsCString uri = NS_ConvertUTF16toUTF8(aUri);
|
||||
uint8_t id = GetURIIdentifier(uri);
|
||||
uri = Substring(uri, strings[id].length);
|
||||
mPayload = Uint8Array::Create(aCx, this, uri.Length() + 1);
|
||||
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
uint8_t* data = JS_GetUint8ArrayData(mPayload, nogc);
|
||||
data[0] = id;
|
||||
memcpy(&data[1], reinterpret_cast<const uint8_t*>(uri.Data()), uri.Length());
|
||||
IncSizeForPayload(uri.Length() + 1);
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::InitPayload(JSContext* aCx, JSObject& aPayload, uint32_t aLen)
|
||||
{
|
||||
mPayload = &aPayload;
|
||||
IncSizeForPayload(aLen);
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::IncSize(uint32_t aCount)
|
||||
{
|
||||
mSize += aCount;
|
||||
}
|
||||
|
||||
void
|
||||
MozNDEFRecord::IncSizeForPayload(uint32_t aLen)
|
||||
{
|
||||
if (aLen > 0xff) {
|
||||
IncSize(3);
|
||||
}
|
||||
|
||||
IncSize(aLen);
|
||||
}
|
||||
|
||||
bool
|
||||
MozNDEFRecord::WriteUint8Array(JSContext* aCx, JSStructuredCloneWriter* aWriter, JSObject* aObj, uint32_t aLen) const
|
||||
{
|
||||
if (!aLen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, aObj);
|
||||
JSAutoCompartment ac(aCx, obj);
|
||||
JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*obj));
|
||||
return JS_WriteTypedArray(aWriter, value);
|
||||
}
|
||||
|
||||
/* static */ uint32_t
|
||||
MozNDEFRecord::GetURIIdentifier(const nsCString& aUri)
|
||||
{
|
||||
using namespace mozilla::dom::WellKnownURIPrefixValues;
|
||||
|
||||
// strings[0] is "", so we start from 1.
|
||||
for (uint32_t i = 1; i < static_cast<uint32_t>(WellKnownURIPrefix::EndGuard_); i++) {
|
||||
if (StringBeginsWith(aUri, nsDependentCString(strings[i].value))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MozNDEFRecord::~MozNDEFRecord()
|
||||
{
|
||||
DropData();
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
struct JSContext;
|
||||
struct JSStructuredCloneWriter;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -36,15 +38,11 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MozNDEFRecord)
|
||||
|
||||
public:
|
||||
MozNDEFRecord(nsISupports* aParent, TNF aTnf = TNF::Empty);
|
||||
|
||||
MozNDEFRecord(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
const MozNDEFRecordOptions& aOptions);
|
||||
|
||||
~MozNDEFRecord();
|
||||
|
||||
nsIDOMWindow* GetParentObject() const
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mWindow;
|
||||
return mParent;
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
@ -54,33 +52,38 @@ public:
|
|||
const MozNDEFRecordOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<MozNDEFRecord>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aURI,
|
||||
ErrorResult& aRv);
|
||||
|
||||
TNF Tnf() const
|
||||
{
|
||||
return mTnf;
|
||||
}
|
||||
|
||||
void GetType(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
|
||||
void GetType(JSContext* /* unused */, JS::MutableHandle<JSObject*> aRetVal) const
|
||||
{
|
||||
if (mType) {
|
||||
JS::ExposeObjectToActiveJS(mType);
|
||||
}
|
||||
retval.set(mType);
|
||||
aRetVal.set(mType);
|
||||
}
|
||||
|
||||
void GetId(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
|
||||
void GetId(JSContext* /* unused */, JS::MutableHandle<JSObject*> aRetVal) const
|
||||
{
|
||||
if (mId) {
|
||||
JS::ExposeObjectToActiveJS(mId);
|
||||
}
|
||||
retval.set(mId);
|
||||
aRetVal.set(mId);
|
||||
}
|
||||
|
||||
void GetPayload(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
|
||||
void GetPayload(JSContext* /* unused */, JS::MutableHandle<JSObject*> aRetVal) const
|
||||
{
|
||||
if (mPayload) {
|
||||
JS::ExposeObjectToActiveJS(mPayload);
|
||||
}
|
||||
retval.set(mPayload);
|
||||
aRetVal.set(mPayload);
|
||||
}
|
||||
|
||||
uint32_t Size() const
|
||||
|
@ -88,14 +91,35 @@ public:
|
|||
return mSize;
|
||||
}
|
||||
|
||||
void GetAsURI(nsAString& aRetVal);
|
||||
|
||||
// Structured clone methods use these to clone MozNDEFRecord.
|
||||
bool WriteStructuredClone(JSContext* aCx, JSStructuredCloneWriter* aWriter) const;
|
||||
bool ReadStructuredClone(JSContext* aCx, JSStructuredCloneReader* aReader);
|
||||
|
||||
protected:
|
||||
~MozNDEFRecord();
|
||||
|
||||
private:
|
||||
MozNDEFRecord() = delete;
|
||||
nsRefPtr<nsPIDOMWindow> mWindow;
|
||||
nsRefPtr<nsISupports> mParent;
|
||||
void HoldData();
|
||||
void DropData();
|
||||
void InitType(JSContext* aCx, const Optional<Nullable<Uint8Array>>& aType);
|
||||
void InitType(JSContext* aCx, const RTD rtd);
|
||||
void InitType(JSContext* aCx, JSObject& aType, uint32_t aLen);
|
||||
void InitId(JSContext* aCx, const Optional<Nullable<Uint8Array>>& aId);
|
||||
void InitId(JSContext* aCx, JSObject& aId, uint32_t aLen);
|
||||
void InitPayload(JSContext* aCx, const Optional<Nullable<Uint8Array>>& aPayload);
|
||||
void InitPayload(JSContext* aCx, const nsAString& aUri);
|
||||
void InitPayload(JSContext* aCx, JSObject& aPayload, uint32_t aLen);
|
||||
void IncSize(uint32_t aCount);
|
||||
void IncSizeForPayload(uint32_t aLen);
|
||||
bool WriteUint8Array(JSContext* aCx, JSStructuredCloneWriter* aWriter, JSObject* aObj, uint32_t aLen) const;
|
||||
|
||||
static bool
|
||||
ValidateTNF(const MozNDEFRecordOptions& aOptions, ErrorResult& aRv);
|
||||
static uint32_t GetURIIdentifier(const nsCString& aUri);
|
||||
|
||||
TNF mTnf;
|
||||
JS::Heap<JSObject*> mType;
|
||||
|
|
|
@ -144,24 +144,6 @@ NfcContentHelper.prototype = {
|
|||
return this._rfState;
|
||||
},
|
||||
|
||||
encodeNDEFRecords: function encodeNDEFRecords(records) {
|
||||
if (!Array.isArray(records)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let encodedRecords = [];
|
||||
for (let i = 0; i < records.length; i++) {
|
||||
let record = records[i];
|
||||
encodedRecords.push({
|
||||
tnf: record.tnf,
|
||||
type: record.type || undefined,
|
||||
id: record.id || undefined,
|
||||
payload: record.payload || undefined,
|
||||
});
|
||||
}
|
||||
return encodedRecords;
|
||||
},
|
||||
|
||||
setFocusApp: function setFocusApp(tabId, isFocus) {
|
||||
cpmm.sendAsyncMessage("NFC:SetFocusApp", {
|
||||
tabId: tabId,
|
||||
|
@ -184,11 +166,10 @@ NfcContentHelper.prototype = {
|
|||
let requestId = callback.getCallbackId();
|
||||
this._requestMap[requestId] = callback;
|
||||
|
||||
let encodedRecords = this.encodeNDEFRecords(records);
|
||||
cpmm.sendAsyncMessage("NFC:WriteNDEF", {
|
||||
requestId: requestId,
|
||||
sessionToken: sessionToken,
|
||||
records: encodedRecords
|
||||
records: records
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -283,11 +264,10 @@ NfcContentHelper.prototype = {
|
|||
callDefaultFoundHandler: function callDefaultFoundHandler(sessionToken,
|
||||
isP2P,
|
||||
records) {
|
||||
let encodedRecords = this.encodeNDEFRecords(records);
|
||||
cpmm.sendAsyncMessage("NFC:CallDefaultFoundHandler",
|
||||
{sessionToken: sessionToken,
|
||||
isP2P: isP2P,
|
||||
records: encodedRecords});
|
||||
records: records});
|
||||
},
|
||||
|
||||
callDefaultLostHandler: function callDefaultLostHandler(sessionToken, isP2P) {
|
||||
|
|
|
@ -663,9 +663,16 @@ Nfc.prototype = {
|
|||
* Process a message from the gMessageManager.
|
||||
*/
|
||||
receiveMessage: function receiveMessage(message) {
|
||||
if (["NFC:ChangeRFState",
|
||||
"NFC:SendFile",
|
||||
"NFC:QueryInfo"].indexOf(message.name) == -1) {
|
||||
// Return early if we don't need the NFC Service.
|
||||
switch (message.name) {
|
||||
case "NFC:QueryInfo":
|
||||
return {rfState: this.rfState};
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (["NFC:ChangeRFState",
|
||||
"NFC:SendFile"].indexOf(message.name) == -1) {
|
||||
// Update the current sessionId before sending to the NFC service.
|
||||
message.data.sessionId = SessionHelper.getId(message.data.sessionToken);
|
||||
}
|
||||
|
@ -704,8 +711,6 @@ Nfc.prototype = {
|
|||
gSystemMessenger.broadcastMessage("nfc-manager-send-file",
|
||||
sysMsg);
|
||||
break;
|
||||
case "NFC:QueryInfo":
|
||||
return {rfState: this.rfState};
|
||||
default:
|
||||
debug("UnSupported : Message Name " + message.name);
|
||||
return null;
|
||||
|
|
|
@ -58,20 +58,23 @@ struct CommandOptions
|
|||
NDEFRecordStruct record;
|
||||
record.mTnf = currentValue[i].mTnf;
|
||||
|
||||
if (currentValue[i].mType.WasPassed()) {
|
||||
const dom::Uint8Array& type = currentValue[i].mType.Value();
|
||||
if (currentValue[i].mType.WasPassed() &&
|
||||
!currentValue[i].mType.Value().IsNull()) {
|
||||
const dom::Uint8Array& type = currentValue[i].mType.Value().Value();
|
||||
type.ComputeLengthAndData();
|
||||
record.mType.AppendElements(type.Data(), type.Length());
|
||||
}
|
||||
|
||||
if (currentValue[i].mId.WasPassed()) {
|
||||
const dom::Uint8Array& id = currentValue[i].mId.Value();
|
||||
if (currentValue[i].mId.WasPassed() &&
|
||||
!currentValue[i].mId.Value().IsNull()) {
|
||||
const dom::Uint8Array& id = currentValue[i].mId.Value().Value();
|
||||
id.ComputeLengthAndData();
|
||||
record.mId.AppendElements(id.Data(), id.Length());
|
||||
}
|
||||
|
||||
if (currentValue[i].mPayload.WasPassed()) {
|
||||
const dom::Uint8Array& payload = currentValue[i].mPayload.Value();
|
||||
if (currentValue[i].mPayload.WasPassed() &&
|
||||
!currentValue[i].mPayload.Value().IsNull()) {
|
||||
const dom::Uint8Array& payload = currentValue[i].mPayload.Value().Value();
|
||||
payload.ComputeLengthAndData();
|
||||
record.mPayload.AppendElements(payload.Data(), payload.Length());
|
||||
}
|
||||
|
|
|
@ -161,17 +161,17 @@ public:
|
|||
|
||||
if (recordStruct.mType.Length() > 0) {
|
||||
record.mType.Construct();
|
||||
record.mType.Value().Init(Uint8Array::Create(cx, recordStruct.mType.Length(), recordStruct.mType.Elements()));
|
||||
record.mType.Value().SetValue().Init(Uint8Array::Create(cx, recordStruct.mType.Length(), recordStruct.mType.Elements()));
|
||||
}
|
||||
|
||||
if (recordStruct.mId.Length() > 0) {
|
||||
record.mId.Construct();
|
||||
record.mId.Value().Init(Uint8Array::Create(cx, recordStruct.mId.Length(), recordStruct.mId.Elements()));
|
||||
record.mId.Value().SetValue().Init(Uint8Array::Create(cx, recordStruct.mId.Length(), recordStruct.mId.Elements()));
|
||||
}
|
||||
|
||||
if (recordStruct.mPayload.Length() > 0) {
|
||||
record.mPayload.Construct();
|
||||
record.mPayload.Value().Init(Uint8Array::Create(cx, recordStruct.mPayload.Length(), recordStruct.mPayload.Elements()));
|
||||
record.mPayload.Value().SetValue().Init(Uint8Array::Create(cx, recordStruct.mPayload.Length(), recordStruct.mPayload.Elements()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,18 +70,7 @@ PluginWidgetParent::~PluginWidgetParent()
|
|||
// A destroy call can actually get skipped if a widget is associated
|
||||
// with the last out-of-process page, make sure and cleanup any left
|
||||
// over widgets if we have them.
|
||||
if (mWidget) {
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)0);
|
||||
mWrapper = nullptr;
|
||||
#elif defined(XP_WIN)
|
||||
::RemovePropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW),
|
||||
kPluginWidgetParentProperty);
|
||||
#endif
|
||||
mWidget->UnregisterPluginWindowForRemoteUpdates();
|
||||
mWidget->Destroy();
|
||||
mWidget = nullptr;
|
||||
}
|
||||
KillWidget();
|
||||
}
|
||||
|
||||
mozilla::dom::TabParent*
|
||||
|
@ -135,6 +124,7 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
|||
// we can send over to content -> plugin.
|
||||
PLUG_NewPluginNativeWindow((nsPluginNativeWindow**)&mWrapper);
|
||||
if (!mWrapper) {
|
||||
KillWidget();
|
||||
return false;
|
||||
}
|
||||
// Give a copy of this to the widget, which handles some update
|
||||
|
@ -147,6 +137,7 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
|||
// If this fails, bail.
|
||||
if (!parentWidget) {
|
||||
*aResult = NS_ERROR_NOT_AVAILABLE;
|
||||
KillWidget();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -158,8 +149,7 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
|||
*aResult = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
|
||||
&initData);
|
||||
if (NS_FAILED(*aResult)) {
|
||||
mWidget->Destroy();
|
||||
mWidget = nullptr;
|
||||
KillWidget();
|
||||
// This should never fail, abort.
|
||||
return false;
|
||||
}
|
||||
|
@ -192,13 +182,29 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
|||
}
|
||||
|
||||
void
|
||||
PluginWidgetParent::Shutdown(ShutdownType aType)
|
||||
PluginWidgetParent::KillWidget()
|
||||
{
|
||||
PWLOG("PluginWidgetParent::KillWidget() widget=%p\n", (void*)mWidget.get());
|
||||
if (mWidget) {
|
||||
mWidget->UnregisterPluginWindowForRemoteUpdates();
|
||||
DebugOnly<nsresult> rv = mWidget->Destroy();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "widget destroy failure");
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)0);
|
||||
mWrapper = nullptr;
|
||||
#elif defined(XP_WIN)
|
||||
::RemovePropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW),
|
||||
kPluginWidgetParentProperty);
|
||||
#endif
|
||||
mWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginWidgetParent::Shutdown(ShutdownType aType)
|
||||
{
|
||||
if (mWidget) {
|
||||
KillWidget();
|
||||
unused << SendParentShutdown(aType);
|
||||
}
|
||||
}
|
||||
|
@ -207,6 +213,7 @@ void
|
|||
PluginWidgetParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
PWLOG("PluginWidgetParent::ActorDestroy()\n");
|
||||
KillWidget();
|
||||
}
|
||||
|
||||
// Called by TabParent's Destroy() in response to an early tear down (Early
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
|
||||
private:
|
||||
void Shutdown(ShutdownType aType);
|
||||
void KillWidget();
|
||||
|
||||
// The chrome side native widget.
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче