Merge m-c to fx-team a=merge CLOSED TREE

This commit is contained in:
Wes Kocher 2015-03-10 16:14:07 -07:00
Родитель 53c080ad33 d8ac0068e5
Коммит 36bade3e67
354 изменённых файлов: 5474 добавлений и 3628 удалений

Просмотреть файл

@ -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;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше