Merge from mozilla-central (yay method barrier removal).

This commit is contained in:
David Anderson 2012-03-28 13:46:36 -07:00
commit 4e1a8fb5ae
297 changed files with 7762 additions and 5442 deletions

View File

@ -99,7 +99,9 @@ endif
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../base \
-I$(srcdir)/../generic \
-I$(srcdir)/../html \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../xul \
-I$(topsrcdir)/other-licenses/atk-1.0 \
$(NULL)

View File

@ -42,12 +42,14 @@
#include "nsAccessibleWrap.h"
#include "nsAccUtils.h"
#include "nsIAccessibleTable.h"
#include "TableAccessible.h"
#include "nsMai.h"
#include "nsArrayUtils.h"
extern "C" {
using namespace mozilla::a11y;
extern "C" {
static AtkObject*
refAtCB(AtkTable *aTable, gint aRow, gint aColumn)
{
@ -208,23 +210,17 @@ getRowExtentAtCB(AtkTable *aTable,
}
static AtkObject*
getCaptionCB(AtkTable *aTable)
getCaptionCB(AtkTable* aTable)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return nsnull;
nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return nsnull;
nsCOMPtr<nsIAccessibleTable> accTable;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
getter_AddRefs(accTable));
NS_ENSURE_TRUE(accTable, nsnull);
TableAccessible* table = accWrap->AsTable();
NS_ENSURE_TRUE(table, nsnull);
nsCOMPtr<nsIAccessible> caption;
nsresult rv = accTable->GetCaption(getter_AddRefs(caption));
if (NS_FAILED(rv) || !caption)
return nsnull;
return nsAccessibleWrap::GetAtkObject(caption);
nsAccessible* caption = table->Caption();
return caption ? nsAccessibleWrap::GetAtkObject(caption) : nsnull;
}
static const gchar*

View File

@ -44,9 +44,6 @@
#include "nsApplicationAccessibleWrap.h"
#include "nsDocAccessible.h"
#include "nsIAccessibleText.h"
#ifdef MOZ_XUL
#include "nsXULTreeAccessible.h"
#endif
#include "nsAccEvent.h"
#include "States.h"

View File

@ -104,8 +104,9 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../generic \
-I$(srcdir)/../html \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../xul \
-I$(srcdir)/../../../layout/generic \
-I$(srcdir)/../../../layout/style \

View File

@ -58,7 +58,7 @@ using namespace mozilla::a11y;
nsARIAGridAccessible::
nsARIAGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
nsAccessibleWrap(aContent, aDoc)
nsAccessibleWrap(aContent, aDoc), xpcAccessibleTable(this)
{
}
@ -70,21 +70,18 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsARIAGridAccessible,
nsIAccessibleTable)
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleTable
//nsAccessNode
NS_IMETHODIMP
nsARIAGridAccessible::GetCaption(nsIAccessible **aCaption)
void
nsARIAGridAccessible::Shutdown()
{
NS_ENSURE_ARG_POINTER(aCaption);
*aCaption = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should be pointed by aria-labelledby on grid?
return NS_ERROR_NOT_IMPLEMENTED;
mTable = nsnull;
nsAccessibleWrap::Shutdown();
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleTable
NS_IMETHODIMP
nsARIAGridAccessible::GetSummary(nsAString &aSummary)
{
@ -710,15 +707,6 @@ nsARIAGridAccessible::UnselectColumn(PRInt32 aColumn)
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
{
NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
*aIsProbablyForLayout = false;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// Protected

View File

@ -42,12 +42,16 @@
#include "nsIAccessibleTable.h"
#include "nsHyperTextAccessibleWrap.h"
#include "TableAccessible.h"
#include "xpcAccessibleTable.h"
/**
* Accessible for ARIA grid and treegrid.
*/
class nsARIAGridAccessible : public nsAccessibleWrap,
public nsIAccessibleTable
public xpcAccessibleTable,
public nsIAccessibleTable,
public mozilla::a11y::TableAccessible
{
public:
nsARIAGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
@ -56,7 +60,13 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessibleTable
NS_DECL_NSIACCESSIBLETABLE
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
// nsAccessible
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
// nsAccessNode
virtual void Shutdown();
protected:
/**

View File

@ -47,9 +47,7 @@
#include "nsARIAMap.h"
#include "nsDocAccessible.h"
#include "nsHyperTextAccessible.h"
#include "nsHTMLTableAccessible.h"
#include "nsTextAccessible.h"
#include "nsXULTreeGridAccessible.h"
#include "nsIDOMXULContainerElement.h"
#include "nsIDOMXULSelectCntrlEl.h"

View File

@ -66,6 +66,11 @@ class nsHTMLImageMapAccessible;
class nsHTMLLIAccessible;
struct nsRoleMapEntry;
class Relation;
namespace mozilla {
namespace a11y {
class TableAccessible;
}
}
class nsTextAccessible;
struct nsRect;
@ -471,6 +476,8 @@ public:
inline bool IsRoot() const { return mFlags & eRootAccessible; }
nsRootAccessible* AsRoot();
virtual mozilla::a11y::TableAccessible* AsTable() { return nsnull; }
inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
nsTextAccessible* AsTextLeaf();

View File

@ -41,15 +41,13 @@
#include "nsCaretAccessible.h"
#include "nsDocAccessibleWrap.h"
#ifdef MOZ_XUL
#include "nsXULTreeAccessible.h"
#endif
#include "nsHashtable.h"
#include "nsCaretAccessible.h"
#include "nsIDocument.h"
#include "nsIDOMEventListener.h"
class nsXULTreeAccessible;
class Relation;
#define NS_ROOTACCESSIBLE_IMPL_CID \

View File

@ -0,0 +1,170 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef TABLE_ACCESSIBLE_H
#define TABLE_ACCESSIBLE_H
#include "nsString.h"
#include "nsTArray.h"
#include "prtypes.h"
class nsAccessible;
namespace mozilla {
namespace a11y {
/**
* Accessible table interface.
*/
class TableAccessible
{
public:
/**
* Return the caption accessible if any for this table.
*/
virtual nsAccessible* Caption() { return nsnull; }
/**
* Get the summary for this table.
*/
virtual void Summary(nsString& aSummary) { aSummary.Truncate(); }
/**
* Return the number of columns in the table.
*/
virtual PRUint32 ColCount() { return 0; }
/**
* Return the number of rows in the table.
*/
virtual PRUint32 RowCount() { return 0; }
/**
* Return the accessible for the cell at the given row and column indices.
*/
virtual nsAccessible* CellAt(PRUint32 aRowIdx, PRUint32 aColIdx) { return nsnull; }
/**
* Return the index of the cell at the given row and column.
*/
virtual PRInt32 CellIndexAt(PRUint32 aRowIdx, PRUint32 aColIdx) { return -1; }
/**
* Return the column index of the cell with the given index.
*/
virtual PRInt32 ColIndexAt(PRUint32 aCellIdx) { return -1; }
/**
* Return the row index of the cell with the given index.
*/
virtual PRInt32 RowIndexAt(PRUint32 aCellIdx) { return -1; }
/**
* Get the row and column indices for the cell at the given index.
*/
virtual void RowAndColIndicesAt(PRUint32 aCellIdx, PRInt32* aRowIdx,
PRInt32* aColIdx) {}
/**
* Return the number of columns occupied by the cell at the given row and
* column indices.
*/
virtual PRUint32 ColExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx) { return 1; }
/**
* Return the number of rows occupied by the cell at the given row and column
* indices.
*/
virtual PRUint32 RowExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx) { return 1; }
/**
* Get the description of the given column.
*/
virtual void ColDescription(PRUint32 aColIdx, nsString& aDescription)
{ aDescription.Truncate(); }
/**
* Get the description for the given row.
*/
virtual void RowDescription(PRUint32 aRowIdx, nsString& aDescription)
{ aDescription.Truncate(); }
/**
* Return true if the given column is selected.
*/
virtual bool IsColSelected(PRUint32 aColIdx) { return false; }
/**
* Return true if the given row is selected.
*/
virtual bool IsRowSelected(PRUint32 aRowIdx) { return false; }
/**
* Return true if the given cell is selected.
*/
virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx) { return false; }
/**
* Return the number of selected cells.
*/
virtual PRUint32 SelectedCellCount() { return 0; }
/**
* Return the number of selected columns.
*/
virtual PRUint32 SelectedColCount() { return 0; }
/**
* Return the number of selected rows.
*/
virtual PRUint32 SelectedRowCount() { return 0; }
/**
* Get the set of selected cells.
*/
virtual void SelectedCells(nsTArray<nsAccessible*>* aCells) {}
/**
* Get the set of selected column indices.
*/
virtual void SelectedColIndices(nsTArray<PRUint32>* aCols) {}
/**
* Get the set of selected row indices.
*/
virtual void SelectedRowIndices(nsTArray<PRUint32>* aRows) {}
/**
* Select the given column unselecting any other selected columns.
*/
virtual void SelectCol(PRUint32 aColIdx) {}
/**
* Select the given row unselecting all other previously selected rows.
*/
virtual void SelectRow(PRUint32 aRowIdx) {}
/**
* Unselect the given column leaving other selected columns selected.
*/
virtual void UnselectCol(PRUint32 aColIdx) {}
/**
* Unselect the given row leaving other selected rows selected.
*/
virtual void UnselectRow(PRUint32 aRowIdx) {}
/**
* Return true if the table is probably for layout.
*/
virtual bool IsProbablyLayoutTable() { return false; }
};
} // namespace a11y
} // namespace mozilla
#endif

View File

@ -73,6 +73,8 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES = \
-I$(srcdir)/../base \
-I$(srcdir)/../generic \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../../../layout/generic \
-I$(srcdir)/../../../layout/xul/base/src \
$(NULL)

View File

@ -436,7 +436,7 @@ nsHTMLTableHeaderCellAccessible::NativeRole()
nsHTMLTableAccessible::
nsHTMLTableAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
nsAccessibleWrap(aContent, aDoc)
nsAccessibleWrap(aContent, aDoc), xpcAccessibleTable(this)
{
}
@ -446,6 +446,16 @@ nsHTMLTableAccessible::
NS_IMPL_ISUPPORTS_INHERITED2(nsHTMLTableAccessible, nsAccessible,
nsHTMLTableAccessible, nsIAccessibleTable)
////////////////////////////////////////////////////////////////////////////////
//nsAccessNode
void
nsHTMLTableAccessible::Shutdown()
{
mTable = nsnull;
nsAccessibleWrap::Shutdown();
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLTableAccessible: nsAccessible implementation
@ -511,9 +521,7 @@ nsHTMLTableAccessible::GetAttributesInternal(nsIPersistentProperties *aAttribute
nsresult rv = nsAccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
bool isProbablyForLayout;
IsProbablyForLayout(&isProbablyForLayout);
if (isProbablyForLayout) {
if (IsProbablyLayoutTable()) {
nsAutoString oldValueUnused;
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
NS_LITERAL_STRING("true"), oldValueUnused);
@ -538,13 +546,11 @@ nsHTMLTableAccessible::RelationByType(PRUint32 aType)
////////////////////////////////////////////////////////////////////////////////
// nsHTMLTableAccessible: nsIAccessibleTable implementation
NS_IMETHODIMP
nsHTMLTableAccessible::GetCaption(nsIAccessible **aCaption)
nsAccessible*
nsHTMLTableAccessible::Caption()
{
NS_ENSURE_ARG_POINTER(aCaption);
NS_IF_ADDREF(*aCaption = Caption());
return NS_OK;
nsAccessible* child = mChildren.SafeElementAt(0, nsnull);
return child && child->Role() == roles::CAPTION ? child : nsnull;
}
NS_IMETHODIMP
@ -1307,8 +1313,7 @@ nsHTMLTableAccessible::Description(nsString& aDescription)
#ifdef SHOW_LAYOUT_HEURISTIC
if (aDescription.IsEmpty()) {
bool isProbablyForLayout;
IsProbablyForLayout(&isProbablyForLayout);
bool isProbablyForLayout = IsProbablyLayoutTable();
aDescription = mLayoutHeuristic;
}
#ifdef DEBUG_A11Y
@ -1357,8 +1362,8 @@ nsHTMLTableAccessible::HasDescendant(const nsAString& aTagName,
return !!foundItem;
}
NS_IMETHODIMP
nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
bool
nsHTMLTableAccessible::IsProbablyLayoutTable()
{
// Implement a heuristic to determine if table is most likely used for layout
// XXX do we want to look for rowspan or colspan, especialy that span all but a couple cells
@ -1370,18 +1375,16 @@ nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
// Change to |#define SHOW_LAYOUT_HEURISTIC DEBUG| before final release
#ifdef SHOW_LAYOUT_HEURISTIC
#define RETURN_LAYOUT_ANSWER(isLayout, heuristic) \
{ *aIsProbablyForLayout = isLayout; \
mLayoutHeuristic = isLayout ? NS_LITERAL_STRING("layout table: ") : NS_LITERAL_STRING("data table: "); \
mLayoutHeuristic += NS_LITERAL_STRING(heuristic); return NS_OK; }
{ \
mLayoutHeuristic = isLayout ? \
NS_LITERAL_STRING("layout table: " heuristic) : \
NS_LITERAL_STRING("data table: " heuristic); \
return isLayout; \
}
#else
#define RETURN_LAYOUT_ANSWER(isLayout, heuristic) { *aIsProbablyForLayout = isLayout; return NS_OK; }
#define RETURN_LAYOUT_ANSWER(isLayout, heuristic) { return isLayout; }
#endif
*aIsProbablyForLayout = false;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsDocAccessible* docAccessible = Document();
if (docAccessible) {
PRUint64 docState = docAccessible->State();

View File

@ -41,6 +41,8 @@
#include "nsHyperTextAccessibleWrap.h"
#include "nsIAccessibleTable.h"
#include "TableAccessible.h"
#include "xpcAccessibleTable.h"
class nsITableLayout;
class nsITableCellLayout;
@ -121,16 +123,28 @@ public:
}
class nsHTMLTableAccessible : public nsAccessibleWrap,
public nsIAccessibleTable
public xpcAccessibleTable,
public nsIAccessibleTable,
public mozilla::a11y::TableAccessible
{
public:
nsHTMLTableAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLETABLE
NS_DECLARE_STATIC_IID_ACCESSOR(NS_TABLEACCESSIBLE_IMPL_CID)
// nsIAccessible Table
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
// TableAccessible
virtual nsAccessible* Caption();
virtual bool IsProbablyLayoutTable();
// nsAccessNode
virtual void Shutdown();
// nsAccessible
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
virtual void Description(nsString& aDescription);
virtual nsresult GetNameInternal(nsAString& aName);
virtual mozilla::a11y::role NativeRole();
@ -138,13 +152,6 @@ public:
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual Relation RelationByType(PRUint32 aRelationType);
// TableAccessible
inline nsAccessible* Caption() const
{
nsAccessible* child = mChildren.SafeElementAt(0, nsnull);
return child && child->Role() == mozilla::a11y::roles::CAPTION ? child : nsnull;
}
// nsHTMLTableAccessible
/**

View File

@ -132,7 +132,7 @@ nsHyperTextAccessible::NativeRole()
return roles::FORM;
if (tag == nsGkAtoms::blockquote || tag == nsGkAtoms::div ||
tag == nsGkAtoms::nav)
tag == nsGkAtoms::section || tag == nsGkAtoms::nav)
return roles::SECTION;
if (tag == nsGkAtoms::h1 || tag == nsGkAtoms::h2 ||
@ -1239,6 +1239,9 @@ nsHyperTextAccessible::GetAttributesInternal(nsIPersistentProperties *aAttribute
if (mContent->Tag() == nsGkAtoms::nav)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("navigation"));
else if (mContent->Tag() == nsGkAtoms::section)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("region"));
else if (mContent->Tag() == nsGkAtoms::footer)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("contentinfo"));

View File

@ -114,7 +114,9 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../base \
-I$(srcdir)/../generic \
-I$(srcdir)/../html \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../xul \
-I$(srcdir)/../../../content/base/src \
-I$(srcdir)/../../../content/events/src \

View File

@ -50,6 +50,7 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \
nsAccEvent.cpp \
nsAccessibleRelation.cpp \
xpcAccessibleTable.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.
@ -59,4 +60,5 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES = \
-I$(srcdir)/../base \
-I$(srcdir)/../generic \
$(NULL)

View File

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "xpcAccessibleTable.h"
#include "nsAccessible.h"
#include "TableAccessible.h"
nsresult
xpcAccessibleTable::GetCaption(nsIAccessible** aCaption)
{
NS_ENSURE_ARG_POINTER(aCaption);
*aCaption = nsnull;
if (!mTable)
return NS_ERROR_FAILURE;
NS_IF_ADDREF(*aCaption = mTable->Caption());
return NS_OK;
}
nsresult
xpcAccessibleTable::IsProbablyForLayout(bool* aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = false;
if (!mTable)
return NS_ERROR_FAILURE;
*aResult = mTable->IsProbablyLayoutTable();
return NS_OK;
}

View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_
#define MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_
#include "nscore.h"
class nsIAccessible;
namespace mozilla {
namespace a11y {
class TableAccessible;
}
}
class xpcAccessibleTable
{
public:
xpcAccessibleTable(mozilla::a11y::TableAccessible* aTable) : mTable(aTable) { }
nsresult GetCaption(nsIAccessible** aCaption);
nsresult IsProbablyForLayout(bool* aIsForLayout);
protected:
mozilla::a11y::TableAccessible* mTable;
};
#define NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE \
NS_IMETHOD GetCaption(nsIAccessible** aCaption) \
{ return xpcAccessibleTable::GetCaption(aCaption); } \
NS_SCRIPTABLE NS_IMETHOD GetSummary(nsAString & aSummary); \
NS_SCRIPTABLE NS_IMETHOD GetColumnCount(PRInt32 *aColumnCount); \
NS_SCRIPTABLE NS_IMETHOD GetRowCount(PRInt32 *aRowCount); \
NS_SCRIPTABLE NS_IMETHOD GetCellAt(PRInt32 rowIndex, PRInt32 columnIndex, nsIAccessible * *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetCellIndexAt(PRInt32 rowIndex, PRInt32 columnIndex, PRInt32 *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetColumnIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetRowIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetRowAndColumnIndicesAt(PRInt32 cellIndex, PRInt32 *rowIndex NS_OUTPARAM, PRInt32 *columnIndex NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetColumnExtentAt(PRInt32 row, PRInt32 column, PRInt32 *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetRowExtentAt(PRInt32 row, PRInt32 column, PRInt32 *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetColumnDescription(PRInt32 columnIndex, nsAString & _retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetRowDescription(PRInt32 rowIndex, nsAString & _retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD IsColumnSelected(PRInt32 columnIndex, bool *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD IsRowSelected(PRInt32 rowIndex, bool *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD IsCellSelected(PRInt32 rowIndex, PRInt32 columnIndex, bool *_retval NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedCellCount(PRUint32 *aSelectedCellCount); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnCount(PRUint32 *aSelectedColumnCount); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedRowCount(PRUint32 *aSelectedRowCount); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedCells(nsIArray * *aSelectedCells); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedCellIndices(PRUint32 *cellsArraySize NS_OUTPARAM, PRInt32 **cellsArray NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnIndices(PRUint32 *rowsArraySize NS_OUTPARAM, PRInt32 **rowsArray NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedRowIndices(PRUint32 *rowsArraySize NS_OUTPARAM, PRInt32 **rowsArray NS_OUTPARAM); \
NS_SCRIPTABLE NS_IMETHOD SelectRow(PRInt32 rowIndex); \
NS_SCRIPTABLE NS_IMETHOD SelectColumn(PRInt32 columnIndex); \
NS_SCRIPTABLE NS_IMETHOD UnselectColumn(PRInt32 columnIndex); \
NS_IMETHOD UnselectRow(PRInt32 aRowIdx); \
NS_IMETHOD IsProbablyForLayout(bool* aResult) \
{ return xpcAccessibleTable::IsProbablyForLayout(aResult); } \
#endif // MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_

View File

@ -72,7 +72,9 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES = \
-I$(srcdir) \
-I$(srcdir)/../base \
-I$(srcdir)/../generic \
-I$(srcdir)/../html \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../../../layout/generic \
-I$(srcdir)/../../../layout/xul/base/src \
$(NULL)

View File

@ -134,7 +134,7 @@ nsXULColumnItemAccessible::DoAction(PRUint8 aIndex)
nsXULListboxAccessible::
nsXULListboxAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
XULSelectControlAccessible(aContent, aDoc)
XULSelectControlAccessible(aContent, aDoc), xpcAccessibleTable(this)
{
nsIContent* parentContent = mContent->GetParent();
if (parentContent) {
@ -164,6 +164,16 @@ nsXULListboxAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_ERROR_NO_INTERFACE;
}
////////////////////////////////////////////////////////////////////////////////
//nsAccessNode
void
nsXULListboxAccessible::Shutdown()
{
mTable = nsnull;
XULSelectControlAccessible::Shutdown();
}
bool
nsXULListboxAccessible::IsMulticolumn()
{
@ -229,15 +239,6 @@ nsXULListboxAccessible::NativeRole()
////////////////////////////////////////////////////////////////////////////////
// nsXULListboxAccessible. nsIAccessibleTable
NS_IMETHODIMP
nsXULListboxAccessible::GetCaption(nsIAccessible **aCaption)
{
NS_ENSURE_ARG_POINTER(aCaption);
*aCaption = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsXULListboxAccessible::GetSummary(nsAString &aSummary)
{
@ -820,15 +821,6 @@ nsXULListboxAccessible::UnselectColumn(PRInt32 aColumn)
return NS_OK;
}
NS_IMETHODIMP
nsXULListboxAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
{
NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
*aIsProbablyForLayout = false;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsXULListboxAccessible: Widgets

View File

@ -40,11 +40,12 @@
#ifndef __nsXULListboxAccessible_h__
#define __nsXULListboxAccessible_h__
#include "nsIAccessibleTable.h"
#include "nsCOMPtr.h"
#include "nsXULMenuAccessible.h"
#include "nsBaseWidgetAccessible.h"
#include "nsIAccessibleTable.h"
#include "TableAccessible.h"
#include "xpcAccessibleTable.h"
#include "XULSelectControlAccessible.h"
class nsIWeakReference;
@ -90,19 +91,27 @@ public:
* A class the represents the XUL Listbox widget.
*/
class nsXULListboxAccessible : public XULSelectControlAccessible,
public nsIAccessibleTable
public xpcAccessibleTable,
public nsIAccessibleTable,
public mozilla::a11y::TableAccessible
{
public:
nsXULListboxAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
virtual ~nsXULListboxAccessible() {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLETABLE
// nsIAccessibleTable
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
// nsAccessNode
virtual void Shutdown();
// nsAccessible
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();

View File

@ -58,7 +58,7 @@ using namespace mozilla::a11y;
nsXULTreeGridAccessible::
nsXULTreeGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
nsXULTreeAccessible(aContent, aDoc)
nsXULTreeAccessible(aContent, aDoc), xpcAccessibleTable(this)
{
}
@ -72,15 +72,6 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeGridAccessible,
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridAccessible: nsIAccessibleTable implementation
NS_IMETHODIMP
nsXULTreeGridAccessible::GetCaption(nsIAccessible **aCaption)
{
NS_ENSURE_ARG_POINTER(aCaption);
*aCaption = nsnull;
return IsDefunct() ? NS_ERROR_FAILURE : NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridAccessible::GetSummary(nsAString &aSummary)
{
@ -570,13 +561,14 @@ nsXULTreeGridAccessible::UnselectColumn(PRInt32 aColumnIndex)
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
{
NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
*aIsProbablyForLayout = false;
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridAccessible: nsAccessNode implementation
return NS_OK;
void
nsXULTreeGridAccessible::Shutdown()
{
mTable = nsnull;
nsXULTreeAccessible::Shutdown();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -39,15 +39,17 @@
#ifndef __nsXULTreeGridAccessible_h__
#define __nsXULTreeGridAccessible_h__
#include "nsIAccessibleTable.h"
#include "nsXULTreeAccessible.h"
#include "TableAccessible.h"
#include "xpcAccessibleTable.h"
/**
* Represents accessible for XUL tree in the case when it has multiple columns.
*/
class nsXULTreeGridAccessible : public nsXULTreeAccessible,
public nsIAccessibleTable
public xpcAccessibleTable,
public nsIAccessibleTable,
public mozilla::a11y::TableAccessible
{
public:
nsXULTreeGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
@ -56,9 +58,13 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessibleTable
NS_DECL_NSIACCESSIBLETABLE
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
// nsAccessNode
virtual void Shutdown();
// nsAccessible
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
virtual mozilla::a11y::role NativeRole();
protected:

View File

@ -24,6 +24,7 @@
testRole("footer", ROLE_FOOTER);
testRole("article", ROLE_DOCUMENT);
testRole("aside", ROLE_NOTE);
testRole("section", ROLE_SECTION); // XXX bug 739612: not a landmark
testRole("main", ROLE_DOCUMENT);
testRole("form", ROLE_FORM);
@ -32,6 +33,7 @@
testAttrs("nav", {"xml-roles" : "navigation"}, true);
testAttrs("footer", {"xml-roles" : "contentinfo"}, true);
testAttrs("aside", {"xml-roles" : "complementary"}, true);
testAttrs("section", {"xml-roles" : "region"}, true);
testAttrs("main", {"xml-roles" : "main"}, true); // // ARIA override
testAttrs("form", {"xml-roles" : "form"}, true);
@ -41,6 +43,7 @@
testAttrs("footer", {"tag" : "footer"}, true);
testAttrs("article", {"tag" : "article"}, true);
testAttrs("aside", {"tag" : "aside"}, true);
testAttrs("section", {"tag" : "section"}, true);
testAttrs("main", {"tag" : "article"}, true);
testAttrs("form", {"tag" : "article"}, true);
@ -68,6 +71,11 @@
title="Change implementation of HTML5 landmark elements to conform">
Bug 610650
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=614310"
title="Map section to pane (like role=region)">
Mozilla Bug 614310
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=734982"
title="Map ARIA role FORM">
@ -82,6 +90,7 @@
<header id="header">a header</header>
<footer id="footer">a footer</footer>
<aside id="aside">by the way I am an aside</aside>
<section id="section">a section</section>
<article id="article">an article</article>
<article id="main" role="main">a main area</article>

View File

@ -53,6 +53,7 @@ const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
const ROLE_PROPERTYPAGE = nsIAccessibleRole.ROLE_PROPERTYPAGE;
const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
const ROLE_RADIOBUTTON = nsIAccessibleRole.ROLE_RADIOBUTTON;
const ROLE_RICH_OPTION = nsIAccessibleRole.ROLE_RICH_OPTION;
const ROLE_ROW = nsIAccessibleRole.ROLE_ROW;
const ROLE_ROWHEADER = nsIAccessibleRole.ROLE_ROWHEADER;
const ROLE_SCROLLBAR = nsIAccessibleRole.ROLE_SCROLLBAR;

View File

@ -57,6 +57,7 @@ _TEST_FILES =\
test_imagemap.html \
test_list_editabledoc.html \
test_list.html \
test_listbox.xul \
test_menu.xul \
test_menubutton.xul \
test_recreation.html \

View File

@ -0,0 +1,180 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Accessible XUL listbox hierarchy tests">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="../common.js" />
<script type="application/javascript"
src="../role.js" />
<script type="application/javascript"
src="../events.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
function insertListitem(aListboxID)
{
this.listboxNode = getNode(aListboxID);
this.listitemNode = document.createElement("listitem");
this.listitemNode.setAttribute("label", "item1");
this.eventSeq = [
new invokerChecker(EVENT_SHOW, this.listitemNode),
new invokerChecker(EVENT_REORDER, this.listboxNode)
];
this.invoke = function insertListitem_invoke()
{
this.listboxNode.insertBefore(this.listitemNode,
this.listboxNode.firstChild);
}
this.finalCheck = function insertListitem_finalCheck()
{
var tree =
{ LISTBOX: [
{
role: ROLE_RICH_OPTION,
name: "item1"
},
{
role: ROLE_RICH_OPTION,
name: "item2"
},
{
role: ROLE_RICH_OPTION,
name: "item3"
},
{
role: ROLE_RICH_OPTION,
name: "item4"
}
] };
testAccessibleTree(this.listboxNode, tree);
}
this.getID = function insertListitem_getID()
{
return "insert listitem ";
}
}
function removeListitem(aListboxID)
{
this.listboxNode = getNode(aListboxID);
this.listitemNode = null;
this.listitem;
function getListitem(aThisObj)
{
return aThisObj.listitem;
}
this.eventSeq = [
new invokerChecker(EVENT_HIDE, getListitem, this),
new invokerChecker(EVENT_REORDER, this.listboxNode)
];
this.invoke = function removeListitem_invoke()
{
this.listitemNode = this.listboxNode.firstChild;
this.listitem = getAccessible(this.listitemNode);
this.listboxNode.removeChild(this.listitemNode);
}
this.finalCheck = function removeListitem_finalCheck()
{
var tree =
{ LISTBOX: [
{
role: ROLE_RICH_OPTION,
name: "item2"
},
{
role: ROLE_RICH_OPTION,
name: "item3"
},
{
role: ROLE_RICH_OPTION,
name: "item4"
}
] };
testAccessibleTree(this.listboxNode, tree);
}
this.getID = function removeListitem_getID()
{
return "remove listitem ";
}
}
//gA11yEventDumpToConsole = true; // debug stuff
var gQueue = null;
function doTest()
{
var tree =
{ LISTBOX: [
{
role: ROLE_RICH_OPTION,
name: "item2"
},
{
role: ROLE_RICH_OPTION,
name: "item3"
},
{
role: ROLE_RICH_OPTION,
name: "item4"
}
] };
testAccessibleTree("listbox", tree);
gQueue = new eventQueue();
gQueue.push(new insertListitem("listbox"));
gQueue.push(new removeListitem("listbox"));
gQueue.invoke(); // Will call SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=656225"
title="XUL listbox accessible tree doesn't get updated">
Mozilla Bug 656225
</a>
<br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<listbox id="listbox" rows="2">
<listitem label="item2"/>
<listitem label="item3"/>
<listitem label="item4"/>
</listbox>
</vbox>
</hbox>
</window>

View File

@ -69,3 +69,4 @@ fi
MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
MOZ_EXTENSION_MANAGER=1
ENABLE_MARIONETTE=1

View File

@ -56,13 +56,14 @@ DIRS = \
app \
$(NULL)
ifeq ($(OS_ARCH),WINNT)
ifdef MAKENSISU
DIRS += installer/windows
endif
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH),WINNT)
ifdef MAKENSISU
# For Windows build the uninstaller during the application build since the
# uninstaller is included with the application for mar file generation.
libs::

View File

@ -4413,7 +4413,6 @@ var FullScreen = {
// and in tabs-on-bottom mode, move them back to the navigation toolbar.
// When there is a chance the tab bar may be collapsed, put window
// controls on nav bar.
var fullscreenflex = document.getElementById("fullscreenflex");
var fullscreenctls = document.getElementById("window-controls");
var navbar = document.getElementById("nav-bar");
var ctlsOnTabbar = window.toolbar.visible &&
@ -4421,14 +4420,12 @@ var FullScreen = {
(TabsOnTop.enabled &&
!gPrefService.getBoolPref("browser.tabs.autoHide")));
if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
fullscreenctls.removeAttribute("flex");
document.getElementById("TabsToolbar").appendChild(fullscreenctls);
// we don't need this space in tabs-on-top mode, so prevent it from
// being shown
fullscreenflex.removeAttribute("fullscreencontrol");
}
else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
fullscreenctls.setAttribute("flex", "1");
navbar.appendChild(fullscreenctls);
fullscreenflex.setAttribute("fullscreencontrol", "true");
}
var controls = document.getElementsByAttribute("fullscreencontrol", "true");
@ -8666,6 +8663,31 @@ let gPrivateBrowsingUI = {
get privateBrowsingEnabled() {
return this._privateBrowsingService.privateBrowsingEnabled;
},
/**
* These accessors are used to support per-window Private Browsing mode.
* For now the getter returns nsIPrivateBrowsingService.privateBrowsingEnabled,
* and the setter should only be used in tests.
*/
get privateWindow() {
return window.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow)
.docShell.QueryInterface(Ci.nsILoadContext)
.usePrivateBrowsing;
},
set privateWindow(val) {
return window.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow)
.docShell.QueryInterface(Ci.nsILoadContext)
.usePrivateBrowsing = val;
}
};

View File

@ -475,7 +475,7 @@
toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;"
fullscreentoolbar="true" mode="icons" customizable="true"
iconsize="large"
defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,fullscreenflex,window-controls"
defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,window-controls"
context="toolbar-context-menu">
<toolbaritem id="unified-back-forward-button" class="chromeclass-toolbar-additional"
@ -697,8 +697,7 @@
</toolbarbutton>
</toolbaritem>
<hbox id="fullscreenflex" flex="1" hidden="true" fullscreencontrol="true"/>
<hbox id="window-controls" hidden="true" fullscreencontrol="true">
<hbox id="window-controls" hidden="true" fullscreencontrol="true" pack="end">
<toolbarbutton id="minimize-button"
tooltiptext="&fullScreenMinimize.tooltip;"
oncommand="window.minimize();"/>

View File

@ -44,9 +44,8 @@ let gDrop = {
* Handles the 'drop' event.
* @param aCell The drop target cell.
* @param aEvent The 'dragexit' event.
* @param aCallback The callback to call when the drop is finished.
*/
drop: function Drop_drop(aCell, aEvent, aCallback) {
drop: function Drop_drop(aCell, aEvent) {
// The cell that is the drop target could contain a pinned site. We need
// to find out where that site has gone and re-pin it there.
if (aCell.containsPinnedSite())
@ -58,7 +57,7 @@ let gDrop = {
this._cancelDelayedArrange();
// Update the grid and move all sites to their new places.
gUpdater.updateGrid(aCallback);
gUpdater.updateGrid();
},
/**

View File

@ -61,13 +61,12 @@ Site.prototype = {
/**
* Unpins the site and calls the given callback when done.
* @param aCallback The callback to be called when finished.
*/
unpin: function Site_unpin(aCallback) {
unpin: function Site_unpin() {
if (this.isPinned()) {
this._updateAttributes(false);
gPinnedLinks.unpin(this._link);
gUpdater.updateGrid(aCallback);
gUpdater.updateGrid();
}
},
@ -82,15 +81,14 @@ Site.prototype = {
/**
* Blocks the site (removes it from the grid) and calls the given callback
* when done.
* @param aCallback The function to be called when finished.
*/
block: function Site_block(aCallback) {
block: function Site_block() {
if (gBlockedLinks.isBlocked(this._link)) {
if (aCallback)
aCallback();
} else {
gBlockedLinks.block(this._link);
gUpdater.updateGrid(aCallback);
gUpdater.updateGrid();
}
},

View File

@ -15,13 +15,13 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8");
yield blockCell(cells[4]);
yield blockCell(4);
checkGrid("0,1,2,3,5,6,7,8,9");
yield blockCell(cells[4]);
yield blockCell(4);
checkGrid("0,1,2,3,6,7,8,9,");
yield blockCell(cells[4]);
yield blockCell(4);
checkGrid("0,1,2,3,7,8,9,,");
// we removed a pinned site
@ -32,7 +32,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1p,2,3,4,5,6,7,8");
yield blockCell(cells[1]);
yield blockCell(1);
checkGrid("0,2,3,4,5,6,7,8,");
// we remove the last site on the grid (which is pinned) and expect the gap
@ -44,7 +44,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8p");
yield blockCell(cells[8]);
yield blockCell(8);
checkGrid("0,1,2,3,4,5,6,7,9");
// we remove the first site on the grid with the last one pinned. all cells
@ -56,6 +56,6 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8p");
yield blockCell(cells[0]);
yield blockCell(0);
checkGrid("1,2,3,4,5,6,7,9,8p");
}

View File

@ -20,21 +20,12 @@ function runTests() {
fillHistory();
yield addNewTabPageTab();
is(cells[0].site.url, URL, "first site is our fake site");
is(getCell(0).site.url, URL, "first site is our fake site");
let page = {
update: function () {
executeSoon(TestRunner.next);
},
observe: function () {}
};
NewTabUtils.allPages.register(page);
whenPagesUpdated();
yield clearHistory();
NewTabUtils.allPages.unregister(page);
ok(!cells[0].site, "the fake site is gone");
ok(!getCell(0).site, "the fake site is gone");
}
function fillHistory() {

View File

@ -14,5 +14,5 @@ function runTests() {
ok(NewTabUtils.allPages.enabled, true, "page is enabled");
NewTabUtils.allPages.enabled = false;
ok(cw.gGrid.node.hasAttribute("page-disabled"), "page is disabled");
ok(getGrid().node.hasAttribute("page-disabled"), "page is disabled");
}

View File

@ -8,41 +8,23 @@ function runTests() {
yield addNewTabPageTab();
checkGridLocked(false, "grid is unlocked");
let cell = cells[0].node;
let site = cells[0].site.node;
let cell = getCell(0).node;
let site = getCell(0).site.node;
let link = site.querySelector(".newtab-link");
sendDragEvent(link, "dragstart");
sendDragEvent("dragstart", link);
checkGridLocked(true, "grid is now locked");
sendDragEvent(link, "dragend");
sendDragEvent("dragend", link);
checkGridLocked(false, "grid isn't locked anymore");
sendDragEvent(cell, "dragstart");
sendDragEvent("dragstart", cell);
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
sendDragEvent(site, "dragstart");
sendDragEvent("dragstart", site);
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
}
function checkGridLocked(aLocked, aMessage) {
is(cw.gGrid.node.hasAttribute("locked"), aLocked, aMessage);
}
function sendDragEvent(aNode, aType) {
let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
let dataTransfer = {
mozUserCancelled: false,
setData: function () null,
setDragImage: function () null,
getData: function () "about:blank"
};
let event = cw.document.createEvent("DragEvents");
event.initDragEvent(aType, true, true, cw, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
is(getGrid().node.hasAttribute("locked"), aLocked, aMessage);
}

View File

@ -8,45 +8,16 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8");
let cell = cells[0].node;
let cell = getCell(0).node;
sendDropEvent(cell, "about:blank#99\nblank");
sendDragEvent("drop", cell, "about:blank#99\nblank");
is(NewTabUtils.pinnedLinks.links[0].url, "about:blank#99",
"first cell is pinned and contains the dropped site");
yield whenPagesUpdated();
checkGrid("99p,0,1,2,3,4,5,6,7");
sendDropEvent(cell, "");
sendDragEvent("drop", cell, "");
is(NewTabUtils.pinnedLinks.links[0].url, "about:blank#99",
"first cell is still pinned with the site we dropped before");
}
function sendDropEvent(aNode, aData) {
let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
let dataTransfer = {
mozUserCancelled: false,
setData: function () null,
setDragImage: function () null,
getData: function () aData,
types: {
contains: function (aType) aType == "text/x-moz-url"
},
mozGetDataAt: function (aType, aIndex) {
if (aIndex || aType != "text/x-moz-url")
return null;
return aData;
},
};
let event = cw.document.createEvent("DragEvents");
event.initDragEvent("drop", true, true, cw, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
}

View File

@ -9,12 +9,13 @@ function runTests() {
checkGrid("0,1,2,3,4,5,6,7,8");
let receivedError = false;
let block = cw.document.querySelector(".newtab-control-block");
let block = getContentDocument().querySelector(".newtab-control-block");
function onError() {
receivedError = true;
}
let cw = getContentWindow();
cw.addEventListener("error", onError);
for (let i = 0; i < 3; i++)

View File

@ -8,15 +8,15 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8");
yield simulateDrop(cells[1]);
yield simulateDrop(1);
checkGrid("0,99p,1,2,3,4,5,6,7");
yield blockCell(cells[1]);
yield blockCell(1);
checkGrid("0,1,2,3,4,5,6,7,8");
yield simulateDrop(cells[1]);
yield simulateDrop(1);
checkGrid("0,99p,1,2,3,4,5,6,7");
yield blockCell(cells[1]);
yield blockCell(1);
checkGrid("0,1,2,3,4,5,6,7,8");
}

View File

@ -11,14 +11,14 @@ function runTests() {
setPinnedLinks("");
yield addNewTabPageTab();
let gridNode = cw.gGrid.node;
let gridNode = getGrid().node;
ok(!gridNode.hasAttribute("page-disabled"), "page is not disabled");
NewTabUtils.allPages.enabled = false;
ok(gridNode.hasAttribute("page-disabled"), "page is disabled");
let oldGridNode = cw.gGrid.node;
let oldGridNode = gridNode;
// create a second new tage page and make sure it's disabled. enable it
// again and check if the former page gets enabled as well.
@ -26,7 +26,7 @@ function runTests() {
ok(gridNode.hasAttribute("page-disabled"), "page is disabled");
// check that no sites have been rendered
is(0, cw.document.querySelectorAll(".site").length, "no sites have been rendered");
is(0, getContentDocument().querySelectorAll(".site").length, "no sites have been rendered");
NewTabUtils.allPages.enabled = true;
ok(!gridNode.hasAttribute("page-disabled"), "page is not disabled");

View File

@ -15,7 +15,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8");
yield simulateDrop(cells[1], cells[0]);
yield simulateDrop(1, 0);
checkGrid("1,0p,2,3,4,5,6,7,8");
// drag a cell to its current cell and make sure it's not pinned afterwards
@ -25,7 +25,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8");
yield simulateDrop(cells[0], cells[0]);
yield simulateDrop(0, 0);
checkGrid("0,1,2,3,4,5,6,7,8");
// ensure that pinned pages aren't moved if that's not necessary
@ -35,7 +35,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1p,2p,3,4,5,6,7,8");
yield simulateDrop(cells[3], cells[0]);
yield simulateDrop(3, 0);
checkGrid("3,1p,2p,0p,4,5,6,7,8");
// pinned sites should always be moved around as blocks. if a pinned site is
@ -46,7 +46,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0p,1p,2,3,4,5,6,7,8");
yield simulateDrop(cells[0], cells[2]);
yield simulateDrop(0, 2);
checkGrid("2p,0p,1p,3,4,5,6,7,8");
// pinned sites should not be pushed out of the grid (unless there are only
@ -57,7 +57,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7p,8p");
yield simulateDrop(cells[8], cells[2]);
yield simulateDrop(8, 2);
checkGrid("0,1,3,4,5,6,7p,8p,2p");
// make sure that pinned sites are re-positioned correctly
@ -67,7 +67,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0p,1p,2p,3,4,5p,6,7,8");
yield simulateDrop(cells[4], cells[0]);
yield simulateDrop(4, 0);
checkGrid("3,1p,2p,4,0p,5p,6,7,8");
// drag a new site onto the very first cell
@ -77,7 +77,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7p,8p");
yield simulateDrop(cells[0]);
yield simulateDrop(0);
checkGrid("99p,0,1,2,3,4,5,7p,8p");
// drag a new site onto the grid and make sure that pinned cells don't get
@ -88,7 +88,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7p,8p");
yield simulateDrop(cells[7]);
yield simulateDrop(7);
checkGrid("0,1,2,3,4,5,7p,99p,8p");
// drag a new site beneath a pinned cell and make sure the pinned cell is
@ -99,7 +99,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8p");
yield simulateDrop(cells[7]);
yield simulateDrop(7);
checkGrid("0,1,2,3,4,5,6,99p,8p");
// drag a new site onto a block of pinned sites and make sure they're shifted
@ -110,6 +110,6 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0p,1p,2p");
yield simulateDrop(cells[1]);
yield simulateDrop(1);
checkGrid("0p,99p,1p,2p,3,4,5,6,7");
}

View File

@ -13,8 +13,9 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0p,1p,2p,3,4,5p,6,7,8");
cw.gDrag._draggedSite = cells[0].site;
let sites = cw.gDropPreview.rearrange(cells[4]);
let cw = getContentWindow();
cw.gDrag._draggedSite = getCell(0).site;
let sites = cw.gDropPreview.rearrange(getCell(4));
cw.gDrag._draggedSite = null;
checkGrid("3,1p,2p,4,0p,5p,6,7,8", sites);

View File

@ -16,7 +16,7 @@ function runTests() {
ok(!pb.privateBrowsingEnabled, "private browsing is disabled");
yield addNewTabPageTab();
pinCell(cells[0]);
pinCell(0);
checkGrid("0p,1,2,3,4,5,6,7,8");
// enter private browsing mode
@ -27,10 +27,10 @@ function runTests() {
checkGrid("0p,1,2,3,4,5,6,7,8");
// modify the grid while we're in pb mode
yield blockCell(cells[1]);
yield blockCell(1);
checkGrid("0p,2,3,4,5,6,7,8");
yield unpinCell(cells[0]);
yield unpinCell(0);
checkGrid("0,2,3,4,5,6,7,8");
// exit private browsing mode

View File

@ -13,16 +13,16 @@ function runTests() {
setPinnedLinks("");
yield addNewTabPageTab();
let resetButton = cw.document.getElementById("toolbar-button-reset");
let resetButton = getContentDocument().getElementById("toolbar-button-reset");
checkGrid("0,1,2,3,4,5,6,7,8");
ok(!resetButton.hasAttribute("modified"), "page is not modified");
yield blockCell(cells[4]);
yield blockCell(4);
checkGrid("0,1,2,3,5,6,7,8,");
ok(resetButton.hasAttribute("modified"), "page is modified");
yield cw.gToolbar.reset(TestRunner.next);
yield getContentWindow().gToolbar.reset(TestRunner.next);
checkGrid("0,1,2,3,4,5,6,7,8");
ok(!resetButton.hasAttribute("modified"), "page is not modified");
}

View File

@ -17,45 +17,45 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1p,2,3,4,5,6,7,8");
let resetButton = cw.document.getElementById("toolbar-button-reset");
let resetButton = getContentDocument().getElementById("toolbar-button-reset");
ok(!resetButton.hasAttribute("modified"), "page is not modified");
let oldCw = cw;
let oldSites = getGrid().sites;
let oldResetButton = resetButton;
// create the new tab page
yield addNewTabPageTab();
checkGrid("0,1p,2,3,4,5,6,7,8");
resetButton = cw.document.getElementById("toolbar-button-reset");
resetButton = getContentDocument().getElementById("toolbar-button-reset");
ok(!resetButton.hasAttribute("modified"), "page is not modified");
// unpin a cell
yield unpinCell(cells[1]);
yield unpinCell(1);
checkGrid("0,1,2,3,4,5,6,7,8");
checkGrid("0,1,2,3,4,5,6,7,8", oldCw.gGrid.sites);
checkGrid("0,1,2,3,4,5,6,7,8", oldSites);
// remove a cell
yield blockCell(cells[1]);
yield blockCell(1);
checkGrid("0,2,3,4,5,6,7,8,9");
checkGrid("0,2,3,4,5,6,7,8,9", oldCw.gGrid.sites);
checkGrid("0,2,3,4,5,6,7,8,9", oldSites);
ok(resetButton.hasAttribute("modified"), "page is modified");
ok(oldResetButton.hasAttribute("modified"), "page is modified");
// insert a new cell by dragging
yield simulateDrop(cells[1]);
yield simulateDrop(1);
checkGrid("0,99p,2,3,4,5,6,7,8");
checkGrid("0,99p,2,3,4,5,6,7,8", oldCw.gGrid.sites);
checkGrid("0,99p,2,3,4,5,6,7,8", oldSites);
// drag a cell around
yield simulateDrop(cells[1], cells[2]);
yield simulateDrop(1, 2);
checkGrid("0,2p,99p,3,4,5,6,7,8");
checkGrid("0,2p,99p,3,4,5,6,7,8", oldCw.gGrid.sites);
checkGrid("0,2p,99p,3,4,5,6,7,8", oldSites);
// reset the new tab page
yield cw.gToolbar.reset(TestRunner.next);
yield getContentWindow().gToolbar.reset(TestRunner.next);
checkGrid("0,1,2,3,4,5,6,7,8");
checkGrid("0,1,2,3,4,5,6,7,8", oldCw.gGrid.sites);
checkGrid("0,1,2,3,4,5,6,7,8", oldSites);
ok(!resetButton.hasAttribute("modified"), "page is not modified");
ok(!oldResetButton.hasAttribute("modified"), "page is not modified");
}

View File

@ -14,7 +14,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,1p,2,3,4,5,6,7,8");
yield unpinCell(cells[1]);
yield unpinCell(1);
checkGrid("0,1,2,3,4,5,6,7,8");
// we have a pinned link that is not anymore in the list of the most-visited
@ -26,7 +26,7 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("0,99p,1,2,3,4,5,6,7");
yield unpinCell(cells[1]);
yield unpinCell(1);
checkGrid("0,1,2,3,4,5,6,7,8");
// we have a pinned link that changed its position since it was pinned. it
@ -37,10 +37,10 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("2,1p,3,4,5,6,7,,0p");
yield unpinCell(cells[1]);
yield unpinCell(1);
checkGrid("1,2,3,4,5,6,7,,0p");
yield unpinCell(cells[8]);
yield unpinCell(8);
checkGrid("0,1,2,3,4,5,6,7,");
// we have pinned link that changed its position since it was pinned. the
@ -51,6 +51,6 @@ function runTests() {
yield addNewTabPageTab();
checkGrid("9p,0,1,2,3,4,5,6,7");
yield unpinCell(cells[0]);
yield unpinCell(0);
checkGrid("0,1,2,3,4,5,6,7,8");
}

View File

@ -16,12 +16,6 @@ registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
});
/**
* Global variables that are accessed by tests.
*/
let cw;
let cells;
/**
* We'll want to restore the original links provider later.
*/
@ -81,6 +75,39 @@ let TestRunner = {
}
};
/**
* Returns the selected tab's content window.
* @return The content window.
*/
function getContentWindow() {
return gBrowser.selectedBrowser.contentWindow;
}
/**
* Returns the selected tab's content document.
* @return The content document.
*/
function getContentDocument() {
return gBrowser.selectedBrowser.contentDocument;
}
/**
* Returns the newtab grid of the selected tab.
* @return The newtab grid.
*/
function getGrid() {
return getContentWindow().gGrid;
}
/**
* Returns the cell at the given index of the selected tab's newtab grid.
* @param aIndex The cell index.
* @return The newtab cell.
*/
function getCell(aIndex) {
return getGrid().cells[aIndex];
}
/**
* Allows to provide a list of links that is used to construct the grid.
* @param aLinksPattern the pattern (see below)
@ -143,18 +170,14 @@ function addNewTabPageTab() {
browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
cw = browser.contentWindow;
if (NewTabUtils.allPages.enabled) {
// Continue when the link cache has been populated.
NewTabUtils.links.populateCache(function () {
cells = cw.gGrid.cells;
executeSoon(TestRunner.next);
});
} else {
TestRunner.next();
}
}, true);
}
@ -169,118 +192,118 @@ function addNewTabPageTab() {
* The fourth cell contains the pinned site 'about:blank#4'.
*/
function checkGrid(aSitesPattern, aSites) {
let valid = true;
let length = aSitesPattern.split(",").length;
let sites = (aSites || getGrid().sites).slice(0, length);
let expected = sites.map(function (aSite) {
if (!aSite)
return "";
aSites = aSites || cw.gGrid.sites;
let pinned = aSite.isPinned();
let pinButton = aSite.node.querySelector(".newtab-control-pin");
let hasPinnedAttr = pinButton.hasAttribute("pinned");
aSitesPattern.split(/\s*,\s*/).forEach(function (id, index) {
let site = aSites[index];
let match = id.match(/^\d+/);
if (pinned != hasPinnedAttr)
ok(false, "invalid state (site.isPinned() != site[pinned])");
// We expect the cell to be empty.
if (!match) {
if (site) {
valid = false;
ok(false, "expected cell#" + index + " to be empty");
}
return;
}
// We expect the cell to contain a site.
if (!site) {
valid = false;
ok(false, "didn't expect cell#" + index + " to be empty");
return;
}
let num = match[0];
// Check the site's url.
if (site.url != "about:blank#" + num) {
valid = false;
is(site.url, "about:blank#" + num, "cell#" + index + " has the wrong url");
}
let shouldBePinned = /p$/.test(id);
let cellContainsPinned = site.isPinned();
let cssClassPinned = site.node && site.node.querySelector(".newtab-control-pin").hasAttribute("pinned");
// Check if the site should be and is pinned.
if (shouldBePinned) {
if (!cellContainsPinned) {
valid = false;
ok(false, "expected cell#" + index + " to be pinned");
} else if (!cssClassPinned) {
valid = false;
ok(false, "expected cell#" + index + " to have css class 'pinned'");
}
} else {
if (cellContainsPinned) {
valid = false;
ok(false, "didn't expect cell#" + index + " to be pinned");
} else if (cssClassPinned) {
valid = false;
ok(false, "didn't expect cell#" + index + " to have css class 'pinned'");
}
}
return aSite.url.replace(/^about:blank#(\d+)$/, "$1") + (pinned ? "p" : "");
});
// If every test passed, say so.
if (valid)
ok(true, "grid status = " + aSitesPattern);
is(aSitesPattern, expected, "grid status = " + aSitesPattern);
}
/**
* Blocks the given cell's site from the grid.
* @param aCell the cell that contains the site to block
* Blocks a site from the grid.
* @param aIndex The cell index.
*/
function blockCell(aCell) {
aCell.site.block(function () executeSoon(TestRunner.next));
function blockCell(aIndex) {
whenPagesUpdated();
getCell(aIndex).site.block();
}
/**
* Pins a given cell's site on a given position.
* @param aCell the cell that contains the site to pin
* @param aIndex the index the defines where the site should be pinned
* Pins a site on a given position.
* @param aIndex The cell index.
* @param aPinIndex The index the defines where the site should be pinned.
*/
function pinCell(aCell, aIndex) {
aCell.site.pin(aIndex);
function pinCell(aIndex, aPinIndex) {
getCell(aIndex).site.pin(aPinIndex);
}
/**
* Unpins the given cell's site.
* @param aCell the cell that contains the site to unpin
* @param aIndex The cell index.
*/
function unpinCell(aCell) {
aCell.site.unpin(function () executeSoon(TestRunner.next));
function unpinCell(aIndex) {
whenPagesUpdated();
getCell(aIndex).site.unpin();
}
/**
* Simulates a drop and drop operation.
* @param aDropTarget the cell that is the drop target
* @param aDragSource the cell that contains the dragged site (optional)
* @param aDropIndex The cell index of the drop target.
* @param aDragIndex The cell index containing the dragged site (optional).
*/
function simulateDrop(aDropTarget, aDragSource) {
let event = {
clientX: 0,
clientY: 0,
dataTransfer: {
mozUserCancelled: false,
setData: function () null,
setDragImage: function () null,
getData: function () "about:blank#99\nblank"
function simulateDrop(aDropIndex, aDragIndex) {
let draggedSite;
let {gDrag: drag, gDrop: drop} = getContentWindow();
let event = createDragEvent("drop", "about:blank#99\nblank");
if (typeof aDragIndex != "undefined")
draggedSite = getCell(aDragIndex).site;
if (draggedSite)
drag.start(draggedSite, event);
whenPagesUpdated();
drop.drop(getCell(aDropIndex), event);
if (draggedSite)
drag.end(draggedSite);
}
/**
* Sends a custom drag event to a given DOM element.
* @param aEventType The drag event's type.
* @param aTarget The DOM element that the event is dispatched to.
* @param aData The event's drag data (optional).
*/
function sendDragEvent(aEventType, aTarget, aData) {
let event = createDragEvent(aEventType, aData);
let ifaceReq = getContentWindow().QueryInterface(Ci.nsIInterfaceRequestor);
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.dispatchDOMEventViaPresShell(aTarget, event, true);
}
/**
* Creates a custom drag event.
* @param aEventType The drag event's type.
* @param aData The event's drag data (optional).
* @return The drag event.
*/
function createDragEvent(aEventType, aData) {
let dataTransfer = {
mozUserCancelled: false,
setData: function () null,
setDragImage: function () null,
getData: function () aData,
types: {
contains: function (aType) aType == "text/x-moz-url"
},
mozGetDataAt: function (aType, aIndex) {
if (aIndex || aType != "text/x-moz-url")
return null;
return aData;
}
};
if (aDragSource)
cw.gDrag.start(aDragSource.site, event);
let event = getContentDocument().createEvent("DragEvents");
event.initDragEvent(aEventType, true, true, getContentWindow(), 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
cw.gDrop.drop(aDropTarget, event, function () executeSoon(TestRunner.next));
if (aDragSource)
cw.gDrag.end(aDragSource.site);
return event;
}
/**

View File

@ -54,10 +54,6 @@
#include "nsIStringBundle.h"
#include "nsXPCOMCID.h"
#define MIGRATION_BUNDLE "chrome://browser/locale/migration/migration.properties"
#define DEFAULT_BOOKMARKS NS_LITERAL_CSTRING("resource:///defaults/profile/bookmarks.html")
void SetUnicharPref(const char* aPref, const nsAString& aValue,
nsIPrefBranch* aPrefs)
{

View File

@ -747,10 +747,6 @@ nsDefaultCommandLineHandler.prototype = {
return this;
},
// List of uri's that were passed via the command line without the app
// running and have already been handled. This is compared against uri's
// opened using DDE on Win32 so we only open one of the requests.
_handledURIs: [ ],
#ifdef XP_WIN
_haveProfile: false,
#endif
@ -784,25 +780,8 @@ nsDefaultCommandLineHandler.prototype = {
try {
var ar;
while ((ar = cmdLine.handleFlagWithParam("url", false))) {
var found = false;
var uri = resolveURIInternal(cmdLine, ar);
// count will never be greater than zero except on Win32.
var count = this._handledURIs.length;
for (var i = 0; i < count; ++i) {
if (this._handledURIs[i].spec == uri.spec) {
this._handledURIs.splice(i, 1);
found = true;
cmdLine.preventDefault = true;
break;
}
}
if (!found) {
urilist.push(uri);
// The requestpending command line flag is only used on Win32.
if (cmdLine.handleFlag("requestpending", false) &&
cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
this._handledURIs.push(uri)
}
urilist.push(uri);
}
}
catch (e) {

View File

@ -1243,13 +1243,7 @@ BrowserGlue.prototype = {
// Need to migrate only if toolbar is customized and the element is not found.
if (currentset &&
currentset.indexOf("bookmarks-menu-button-container") == -1) {
if (currentset.indexOf("fullscreenflex") != -1) {
currentset = currentset.replace(/(^|,)fullscreenflex($|,)/,
"$1bookmarks-menu-button-container,fullscreenflex$2")
}
else {
currentset += ",bookmarks-menu-button-container";
}
currentset += ",bookmarks-menu-button-container";
this._setPersist(toolbarResource, currentsetResource, currentset);
}
}

View File

@ -193,9 +193,9 @@ PrivateBrowsingService.prototype = {
if (!this._quitting && this._saveSession) {
let browserWindow = this._getBrowserWindow();
// if there are open browser windows, load a dummy session to get a distinct
// if there are open browser windows, load a dummy session to get a distinct
// separation between private and non-private sessions
if (browserWindow) {
if (browserWindow) {
// set an empty session to transition from/to pb mode, see bug 476463
ss.setBrowserState(blankState);
@ -217,7 +217,9 @@ PrivateBrowsingService.prototype = {
.getInterface(Ci.nsIXULWindow)
.docShell.contentViewer.resetCloseWindow();
}
}
if (!this._quitting) {
var windowsEnum = Services.wm.getEnumerator("navigator:browser");
while (windowsEnum.hasMoreElements()) {
var window = windowsEnum.getNext();

View File

@ -58,21 +58,31 @@ function test() {
ok(gPrivateBrowsingUI, "The gPrivateBrowsingUI object exists");
is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started initially");
is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
ok(pbMenuItem, "The Private Browsing menu item exists");
is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
gPrivateBrowsingUI.toggleMode();
is(pb.privateBrowsingEnabled, true, "The private browsing mode should be started");
is(gPrivateBrowsingUI.privateBrowsingEnabled, true, "gPrivateBrowsingUI should expose the correct private browsing status");
is(gPrivateBrowsingUI.privateWindow, true, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
// check to see if the Private Browsing mode was activated successfully
is(observerData, "enter", "Private Browsing mode was activated using the gPrivateBrowsingUI object");
is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("stoplabel"), "The Private Browsing menu item should read \"Stop Private Browsing\"");
gPrivateBrowsingUI.toggleMode()
is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started");
is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
// check to see if the Private Browsing mode was deactivated successfully
is(observerData, "exit", "Private Browsing mode was deactivated using the gPrivateBrowsingUI object");
is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
// These are tests for the privateWindow setter. Note that the setter should
// not be used anywhere else for now!
gPrivateBrowsingUI.privateWindow = true;
is(gPrivateBrowsingUI.privateWindow, true, "gPrivateBrowsingUI should accept the correct per-window private browsing status");
gPrivateBrowsingUI.privateWindow = false;
is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should accept the correct per-window private browsing status");
// now, test using the <command> object
let cmd = document.getElementById("Tools:PrivateBrowsing");
isnot(cmd, null, "XUL command object for the private browsing service exists");

View File

@ -77,7 +77,10 @@
#define INITGUID
#include <shlobj.h>
#pragma comment(lib, "shlwapi.lib") // for SHDeleteKeyW
#include <mbstring.h>
#include <shlwapi.h>
#ifndef MAX_BUF
#define MAX_BUF 4096
@ -129,23 +132,17 @@ OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
//
// HKCU\SOFTWARE\Classes\FirefoxHTML\
// DefaultIcon (default) REG_SZ <apppath>,1
// shell\open\command (default) REG_SZ <apppath> -requestPending -osint -url "%1"
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
// shell\open\ddeexec NoActivateHandler REG_SZ
// \Application (default) REG_SZ Firefox
// \Topic (default) REG_SZ WWW_OpenURL
// shell\open\command (default) REG_SZ <apppath> -osint -url "%1"
// shell\open\ddeexec (default) REG_SZ <empty string>
//
// - Windows Vista Protocol Handler
// - Windows Vista and above Protocol Handler
//
// HKCU\SOFTWARE\Classes\FirefoxURL\ (default) REG_SZ <appname> URL
// EditFlags REG_DWORD 2
// FriendlyTypeName REG_SZ <appname> URL
// DefaultIcon (default) REG_SZ <apppath>,1
// shell\open\command (default) REG_SZ <apppath> -requestPending -osint -url "%1"
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
// shell\open\ddeexec NoActivateHandler REG_SZ
// \Application (default) REG_SZ Firefox
// \Topic (default) REG_SZ WWW_OpenURL
// shell\open\command (default) REG_SZ <apppath> -osint -url "%1"
// shell\open\ddeexec (default) REG_SZ <empty string>
//
// - Protocol Mappings
// -----------------
@ -155,13 +152,10 @@ OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
//
// HKCU\SOFTWARE\Classes\<protocol>\
// DefaultIcon (default) REG_SZ <apppath>,1
// shell\open\command (default) REG_SZ <apppath> -requestPending -osint -url "%1"
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
// shell\open\ddeexec NoActivateHandler REG_SZ
// \Application (default) REG_SZ Firefox
// \Topic (default) REG_SZ WWW_OpenURL
// shell\open\command (default) REG_SZ <apppath> -osint -url "%1"
// shell\open\ddeexec (default) REG_SZ <empty string>
//
// - Windows Start Menu (Win2K SP2, XP SP1, and newer)
// - Windows Start Menu (XP SP1 and newer)
// -------------------------------------------------
// The following keys are set to make Firefox appear in the Start Menu as the
// browser:
@ -180,19 +174,22 @@ OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
// shell\safemode\command (default) REG_SZ <apppath> -safe-mode
//
// The values checked are all default values so the value name is not needed.
typedef struct {
char* keyName;
char* valueName;
char* valueData;
char* oldValueData;
} SETTING;
#define APP_REG_NAME L"Firefox"
#define CLS_HTML "FirefoxHTML"
#define CLS_URL "FirefoxURL"
#define VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
#define VAL_FILE_ICON "%APPPATH%,1"
#define VAL_OPEN "\"%APPPATH%\" -osint -url \"%1\""
#define OLD_VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
#define DI "\\DefaultIcon"
#define SOP "\\shell\\open\\command"
#define SOC "\\shell\\open\\command"
#define SOD "\\shell\\open\\ddeexec"
// Used for updating the FTP protocol handler's shell open command under HKCU.
#define FTP_SOC L"Software\\Classes\\ftp\\shell\\open\\command"
#define MAKE_KEY_NAME1(PREFIX, MID) \
PREFIX MID
@ -201,19 +198,37 @@ typedef struct {
// Firefox is the default browser for file handlers since other applications
// (e.g. MS Office) may modify the DefaultIcon registry key value to add Icon
// Handlers. see http://msdn2.microsoft.com/en-us/library/aa969357.aspx for
// more info.
// more info. The FTP protocol is not checked so advanced users can set the FTP
// handler to another application and still have Firefox check if it is the
// default HTTP and HTTPS handler.
static SETTING gSettings[] = {
// File Handler Class
{ MAKE_KEY_NAME1(CLS_HTML, SOP), "", VAL_OPEN },
{ MAKE_KEY_NAME1("FirefoxHTML", SOC), VAL_OPEN, OLD_VAL_OPEN },
// Protocol Handler Class - for Vista and above
{ MAKE_KEY_NAME1(CLS_URL, SOP), "", VAL_OPEN },
{ MAKE_KEY_NAME1("FirefoxURL", SOC), VAL_OPEN, OLD_VAL_OPEN },
// Protocol Handlers
{ MAKE_KEY_NAME1("HTTP", DI), "", VAL_FILE_ICON },
{ MAKE_KEY_NAME1("HTTP", SOP), "", VAL_OPEN },
{ MAKE_KEY_NAME1("HTTPS", DI), "", VAL_FILE_ICON },
{ MAKE_KEY_NAME1("HTTPS", SOP), "", VAL_OPEN }
{ MAKE_KEY_NAME1("HTTP", DI), VAL_FILE_ICON },
{ MAKE_KEY_NAME1("HTTP", SOC), VAL_OPEN, OLD_VAL_OPEN },
{ MAKE_KEY_NAME1("HTTPS", DI), VAL_FILE_ICON },
{ MAKE_KEY_NAME1("HTTPS", SOC), VAL_OPEN, OLD_VAL_OPEN }
};
// The settings to disable DDE are separate from the default browser settings
// since they are only checked when Firefox is the default browser and if they
// are incorrect they are fixed without notifying the user.
static SETTING gDDESettings[] = {
// File Handler Class
{ MAKE_KEY_NAME1("Software\\Classes\\FirefoxHTML", SOD) },
// Protocol Handler Class - for Vista and above
{ MAKE_KEY_NAME1("Software\\Classes\\FirefoxURL", SOD) },
// Protocol Handlers
{ MAKE_KEY_NAME1("Software\\Classes\\FTP", SOD) },
{ MAKE_KEY_NAME1("Software\\Classes\\HTTP", SOD) },
{ MAKE_KEY_NAME1("Software\\Classes\\HTTPS", SOD) }
};
nsresult
@ -245,11 +260,10 @@ LaunchHelper(nsAutoString& aPath)
STARTUPINFOW si = {sizeof(si), 0};
PROCESS_INFORMATION pi = {0};
BOOL ok = CreateProcessW(NULL, (LPWSTR)aPath.get(), NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);
if (!ok)
if (!CreateProcessW(NULL, (LPWSTR)aPath.get(), NULL, NULL, FALSE, 0, NULL,
NULL, &si, &pi)) {
return NS_ERROR_FAILURE;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
@ -367,9 +381,6 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
if (aStartupCheck)
mCheckedThisSession = true;
SETTING* settings;
SETTING* end = gSettings + sizeof(gSettings)/sizeof(SETTING);
*aIsDefaultBrowser = true;
PRUnichar exePath[MAX_BUF];
@ -383,40 +394,171 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
nsAutoString appLongPath(exePath);
HKEY theKey;
DWORD res;
nsresult rv;
PRUnichar currValue[MAX_BUF];
for (settings = gSettings; settings < end; ++settings) {
NS_ConvertUTF8toUTF16 dataLongPath(settings->valueData);
NS_ConvertUTF8toUTF16 key(settings->keyName);
NS_ConvertUTF8toUTF16 value(settings->valueName);
PRInt32 offset = dataLongPath.Find("%APPPATH%");
dataLongPath.Replace(offset, 9, appLongPath);
::ZeroMemory(currValue, sizeof(currValue));
HKEY theKey;
rv = OpenKeyForReading(HKEY_CLASSES_ROOT, key, &theKey);
SETTING* settings;
SETTING* end = gSettings + sizeof(gSettings) / sizeof(SETTING);
for (settings = gSettings; settings < end; ++settings) {
NS_ConvertUTF8toUTF16 keyName(settings->keyName);
NS_ConvertUTF8toUTF16 valueData(settings->valueData);
PRInt32 offset = valueData.Find("%APPPATH%");
valueData.Replace(offset, 9, appLongPath);
rv = OpenKeyForReading(HKEY_CLASSES_ROOT, keyName, &theKey);
if (NS_FAILED(rv)) {
*aIsDefaultBrowser = false;
return NS_OK;
}
::ZeroMemory(currValue, sizeof(currValue));
DWORD len = sizeof currValue;
DWORD res = ::RegQueryValueExW(theKey, PromiseFlatString(value).get(),
NULL, NULL, (LPBYTE)currValue, &len);
// Close the key we opened.
res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue, &len);
// Close the key that was opened.
::RegCloseKey(theKey);
if (REG_FAILED(res) ||
!dataLongPath.Equals(currValue, CaseInsensitiveCompare)) {
// Key wasn't set, or was set to something other than our registry entry
*aIsDefaultBrowser = false;
return NS_OK;
!valueData.Equals(currValue, CaseInsensitiveCompare)) {
// Key wasn't set or was set to something other than our registry entry.
NS_ConvertUTF8toUTF16 oldValueData(settings->oldValueData);
offset = oldValueData.Find("%APPPATH%");
oldValueData.Replace(offset, 9, appLongPath);
// The current registry value doesn't match the current or the old format.
if (!oldValueData.Equals(currValue, CaseInsensitiveCompare)) {
*aIsDefaultBrowser = false;
return NS_OK;
}
res = ::RegOpenKeyExW(HKEY_CLASSES_ROOT, PromiseFlatString(keyName).get(),
0, KEY_SET_VALUE, &theKey);
if (REG_FAILED(res)) {
// If updating the open command fails try to update it using the helper
// application when setting Firefox as the default browser.
*aIsDefaultBrowser = false;
return NS_OK;
}
const nsString &flatValue = PromiseFlatString(valueData);
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
(const BYTE *) flatValue.get(),
(flatValue.Length() + 1) * sizeof(PRUnichar));
// Close the key that was created.
::RegCloseKey(theKey);
if (REG_FAILED(res)) {
// If updating the open command fails try to update it using the helper
// application when setting Firefox as the default browser.
*aIsDefaultBrowser = false;
return NS_OK;
}
}
}
// Only check if Firefox is the default browser on Vista if the previous
// checks show that Firefox is the default browser.
if (*aIsDefaultBrowser)
// Only check if Firefox is the default browser on Vista and above if the
// previous checks show that Firefox is the default browser.
if (*aIsDefaultBrowser) {
IsDefaultBrowserVista(aIsDefaultBrowser);
}
// To handle the case where DDE isn't disabled due for a user because there
// account didn't perform a Firefox update this will check if Firefox is the
// default browser and if dde is disabled for each handler
// and if it isn't disable it. When Firefox is not the default browser the
// helper application will disable dde for each handler.
if (*aIsDefaultBrowser) {
// Check ftp settings
end = gDDESettings + sizeof(gDDESettings) / sizeof(SETTING);
for (settings = gDDESettings; settings < end; ++settings) {
NS_ConvertUTF8toUTF16 keyName(settings->keyName);
rv = OpenKeyForReading(HKEY_CURRENT_USER, keyName, &theKey);
if (NS_FAILED(rv)) {
::RegCloseKey(theKey);
// If disabling DDE fails try to disable it using the helper
// application when setting Firefox as the default browser.
*aIsDefaultBrowser = false;
return NS_OK;
}
::ZeroMemory(currValue, sizeof(currValue));
DWORD len = sizeof currValue;
res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue,
&len);
// Close the key that was opened.
::RegCloseKey(theKey);
if (REG_FAILED(res) || PRUnichar('\0') != *currValue) {
// Key wasn't set or was set to something other than our registry entry.
// Delete the key along with all of its childrean and then recreate it.
const nsString &flatName = PromiseFlatString(keyName);
::SHDeleteKeyW(HKEY_CURRENT_USER, flatName.get());
res = ::RegCreateKeyExW(HKEY_CURRENT_USER, flatName.get(), 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
&theKey, NULL);
if (REG_FAILED(res)) {
// If disabling DDE fails try to disable it using the helper
// application when setting Firefox as the default browser.
*aIsDefaultBrowser = false;
return NS_OK;
}
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ, (const BYTE *) L"",
sizeof(PRUnichar));
// Close the key that was created.
::RegCloseKey(theKey);
if (REG_FAILED(res)) {
// If disabling DDE fails try to disable it using the helper
// application when setting Firefox as the default browser.
*aIsDefaultBrowser = false;
return NS_OK;
}
}
}
// Update the FTP protocol handler's shell open command if it is the old
// format.
res = ::RegOpenKeyExW(HKEY_CURRENT_USER, FTP_SOC, 0, KEY_ALL_ACCESS,
&theKey);
// Don't update the FTP protocol handler's shell open command when opening
// its registry key fails under HKCU since it most likely doesn't exist.
if (NS_FAILED(rv)) {
return NS_OK;
}
NS_ConvertUTF8toUTF16 oldValueOpen(OLD_VAL_OPEN);
PRInt32 offset = oldValueOpen.Find("%APPPATH%");
oldValueOpen.Replace(offset, 9, appLongPath);
::ZeroMemory(currValue, sizeof(currValue));
DWORD len = sizeof currValue;
res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue,
&len);
// Don't update the FTP protocol handler's shell open command when the
// current registry value doesn't exist or matches the old format.
if (REG_FAILED(res) ||
!oldValueOpen.Equals(currValue, CaseInsensitiveCompare)) {
::RegCloseKey(theKey);
return NS_OK;
}
NS_ConvertUTF8toUTF16 valueData(VAL_OPEN);
valueData.Replace(offset, 9, appLongPath);
const nsString &flatValue = PromiseFlatString(valueData);
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
(const BYTE *) flatValue.get(),
(flatValue.Length() + 1) * sizeof(PRUnichar));
// Close the key that was created.
::RegCloseKey(theKey);
// If updating the FTP protocol handlers shell open command fails try to
// update it using the helper application when setting Firefox as the
// default browser.
if (REG_FAILED(res)) {
*aIsDefaultBrowser = false;
}
}
return NS_OK;
}

View File

@ -25,9 +25,6 @@ const Ci = Components.interfaces;
Cu.import("resource:///modules/PageThumbs.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
@ -104,268 +101,252 @@ function Channel(aURI) {
}
Channel.prototype = {
/**
* Tracks if the channel has been opened, yet.
*/
_uri: null,
_referrer: null,
_canceled: false,
_status: Cr.NS_OK,
_isPending: false,
_wasOpened: false,
_responseText: "OK",
_responseStatus: 200,
_responseHeaders: null,
_requestMethod: "GET",
_requestStarted: false,
_allowPipelining: true,
_requestSucceeded: true,
/* :::::::: nsIChannel ::::::::::::::: */
get URI() this._uri,
owner: null,
notificationCallbacks: null,
get securityInfo() null,
contentType: PageThumbs.contentType,
contentCharset: null,
contentLength: -1,
get contentDisposition() {
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
},
get contentDispositionFilename() {
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
},
get contentDispositionHeader() {
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
},
open: function Channel_open() {
throw (Components.returnCode = Cr.NS_ERROR_NOT_IMPLEMENTED);
},
/**
* Opens this channel asynchronously.
* @param aListener The listener that receives the channel data when available.
* @param aContext A custom context passed to the listener's methods.
*/
asyncOpen: function Channel_asyncOpen(aListener, aContext) {
if (this._isPending)
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
if (this._wasOpened)
throw Cr.NS_ERROR_ALREADY_OPENED;
throw (Components.returnCode = Cr.NS_ERROR_ALREADY_OPENED);
if (this.canceled)
return;
this._listener = aListener;
this._context = aContext;
if (this._canceled)
return (Components.returnCode = this._status);
this._isPending = true;
this._wasOpened = true;
// Try to read the data from the thumbnail cache.
this._readCache(function (aData) {
let telemetryThumbnailFound = true;
this._listener = aListener;
this._context = aContext;
// Update response if there's no data.
if (!aData) {
this._responseStatus = 404;
this._responseText = "Not Found";
telemetryThumbnailFound = false;
}
if (this.loadGroup)
this.loadGroup.addRequest(this, null);
Services.telemetry.getHistogramById("FX_THUMBNAILS_HIT_OR_MISS")
.add(telemetryThumbnailFound);
if (this._canceled)
return;
this._startRequest();
if (!this.canceled) {
this._addToLoadGroup();
if (aData)
this._serveData(aData);
if (!this.canceled)
this._stopRequest();
}
}.bind(this));
},
/**
* Reads a data stream from the cache entry.
* @param aCallback The callback the data is passed to.
*/
_readCache: function Channel_readCache(aCallback) {
let {url} = parseURI(this._uri);
// Return early if there's no valid URL given.
if (!url) {
aCallback(null);
this._serveThumbnailNotFound();
return;
}
// Try to get a cache entry.
PageThumbsCache.getReadEntry(url, function (aEntry) {
let inputStream = aEntry && aEntry.openInputStream(0);
function closeEntryAndFinish(aData) {
if (aEntry) {
aEntry.close();
}
aCallback(aData);
}
// Check if we have a valid entry and if it has any data.
if (!inputStream || !inputStream.available()) {
closeEntryAndFinish();
if (aEntry)
aEntry.close();
this._serveThumbnailNotFound();
return;
}
try {
// Read the cache entry's data.
NetUtil.asyncFetch(inputStream, function (aData, aStatus) {
// We might have been canceled while waiting.
if (this.canceled)
return;
this._entry = aEntry;
this._pump = Cc["@mozilla.org/network/input-stream-pump;1"].
createInstance(Ci.nsIInputStreamPump);
// Check if we have a valid data stream.
if (!Components.isSuccessCode(aStatus) || !aData.available())
aData = null;
this._pump.init(inputStream, -1, -1, 0, 0, true);
this._pump.asyncRead(this, null);
closeEntryAndFinish(aData);
}.bind(this));
} catch (e) {
closeEntryAndFinish();
}
this._trackThumbnailHitOrMiss(true);
}.bind(this));
},
/**
* Calls onStartRequest on the channel listener.
* Serves a "404 Not Found" if we didn't find the requested thumbnail.
*/
_startRequest: function Channel_startRequest() {
try {
this._listener.onStartRequest(this, this._context);
} catch (e) {
// The listener might throw if the request has been canceled.
this.cancel(Cr.NS_BINDING_ABORTED);
}
_serveThumbnailNotFound: function Channel_serveThumbnailNotFound() {
this._responseStatus = 404;
this._responseText = "Not Found";
this._requestSucceeded = false;
this.onStartRequest(this, null);
this.onStopRequest(this, null, Cr.NS_OK);
this._trackThumbnailHitOrMiss(false);
},
/**
* Calls onDataAvailable on the channel listener and passes the data stream.
* @param aData The data to be delivered.
* Implements telemetry tracking for thumbnail cache hits and misses.
* @param aFound Whether the thumbnail was found.
*/
_serveData: function Channel_serveData(aData) {
try {
let available = aData.available();
this._listener.onDataAvailable(this, this._context, aData, 0, available);
} catch (e) {
// The listener might throw if the request has been canceled.
this.cancel(Cr.NS_BINDING_ABORTED);
}
_trackThumbnailHitOrMiss: function Channel_trackThumbnailHitOrMiss(aFound) {
Services.telemetry.getHistogramById("FX_THUMBNAILS_HIT_OR_MISS")
.add(aFound);
},
/**
* Calls onStopRequest on the channel listener.
*/
_stopRequest: function Channel_stopRequest() {
try {
this._listener.onStopRequest(this, this._context, this.status);
} catch (e) {
// This might throw but is generally ignored.
}
/* :::::::: nsIStreamListener ::::::::::::::: */
// The request has finished, clean up after ourselves.
this._cleanup();
onStartRequest: function Channel_onStartRequest(aRequest, aContext) {
if (!this.canceled && Components.isSuccessCode(this._status))
this._status = aRequest.status;
this._requestStarted = true;
this._listener.onStartRequest(this, this._context);
},
/**
* Adds this request to the load group, if any.
*/
_addToLoadGroup: function Channel_addToLoadGroup() {
onDataAvailable: function Channel_onDataAvailable(aRequest, aContext,
aInStream, aOffset, aCount) {
this._listener.onDataAvailable(this, this._context, aInStream, aOffset, aCount);
},
onStopRequest: function Channel_onStopRequest(aRequest, aContext, aStatus) {
this._isPending = false;
this._status = aStatus;
this._listener.onStopRequest(this, this._context, aStatus);
this._listener = null;
this._context = null;
if (this._entry)
this._entry.close();
if (this.loadGroup)
this.loadGroup.addRequest(this, this._context);
this.loadGroup.removeRequest(this, null, aStatus);
},
/**
* Removes this request from its load group, if any.
*/
_removeFromLoadGroup: function Channel_removeFromLoadGroup() {
if (!this.loadGroup)
/* :::::::: nsIRequest ::::::::::::::: */
get status() this._status,
get name() this._uri.spec,
isPending: function Channel_isPending() this._isPending,
loadFlags: Ci.nsIRequest.LOAD_NORMAL,
loadGroup: null,
cancel: function Channel_cancel(aStatus) {
if (this._canceled)
return;
try {
this.loadGroup.removeRequest(this, this._context, this.status);
} catch (e) {
// This might throw but is ignored.
}
this._canceled = true;
this._status = aStatus;
if (this._pump)
this._pump.cancel(aStatus);
},
/**
* Cleans up the channel when the request has finished.
*/
_cleanup: function Channel_cleanup() {
this._removeFromLoadGroup();
this.loadGroup = null;
this._isPending = false;
delete this._listener;
delete this._context;
suspend: function Channel_suspend() {
if (this._pump)
this._pump.suspend();
},
/* :::::::: nsIChannel ::::::::::::::: */
contentType: PageThumbs.contentType,
contentLength: -1,
owner: null,
contentCharset: null,
notificationCallbacks: null,
get URI() this._uri,
get securityInfo() null,
/**
* Opens this channel synchronously. Not supported.
*/
open: function Channel_open() {
// Synchronous data delivery is not implemented.
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
resume: function Channel_resume() {
if (this._pump)
this._pump.resume();
},
/* :::::::: nsIHttpChannel ::::::::::::::: */
redirectionLimit: 10,
requestMethod: "GET",
allowPipelining: true,
referrer: null,
get referrer() this._referrer,
get requestSucceeded() true,
set referrer(aReferrer) {
if (this._wasOpened)
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
_responseStatus: 200,
get responseStatus() this._responseStatus,
_responseText: "OK",
get responseStatusText() this._responseText,
/**
* Checks if the server sent the equivalent of a "Cache-control: no-cache"
* response header.
* @return Always false.
*/
isNoCacheResponse: function () false,
/**
* Checks if the server sent the equivalent of a "Cache-control: no-cache"
* response header.
* @return Always false.
*/
isNoStoreResponse: function () false,
/**
* Returns the value of a particular request header. Not implemented.
*/
getRequestHeader: function Channel_getRequestHeader() {
throw Cr.NS_ERROR_NOT_AVAILABLE;
this._referrer = aReferrer;
},
get requestMethod() this._requestMethod,
set requestMethod(aMethod) {
if (this._wasOpened)
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
this._requestMethod = aMethod.toUpperCase();
},
get allowPipelining() this._allowPipelining,
set allowPipelining(aAllow) {
if (this._wasOpened)
throw (Components.returnCode = Cr.NS_ERROR_FAILURE);
this._allowPipelining = aAllow;
},
redirectionLimit: 10,
get responseStatus() {
if (this._requestStarted)
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
return this._responseStatus;
},
get responseStatusText() {
if (this._requestStarted)
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
return this._responseText;
},
get requestSucceeded() {
if (this._requestStarted)
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
return this._requestSucceeded;
},
isNoCacheResponse: function Channel_isNoCacheResponse() false,
isNoStoreResponse: function Channel_isNoStoreResponse() false,
getRequestHeader: function Channel_getRequestHeader() {
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
},
/**
* This method is called to set the value of a particular request header.
* Not implemented.
*/
setRequestHeader: function Channel_setRequestHeader() {
if (this._wasOpened)
throw Cr.NS_ERROR_IN_PROGRESS;
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
},
/**
* Call this method to visit all request headers. Not implemented.
*/
visitRequestHeaders: function () {},
visitRequestHeaders: function Channel_visitRequestHeaders() {},
/**
* Gets the value of a particular response header.
* @param aHeader The case-insensitive name of the response header to query.
* @return The header value.
*/
getResponseHeader: function Channel_getResponseHeader(aHeader) {
let name = aHeader.toLowerCase();
if (name in this._responseHeaders)
return this._responseHeaders[name];
throw Cr.NS_ERROR_NOT_AVAILABLE;
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
},
/**
* This method is called to set the value of a particular response header.
* @param aHeader The case-insensitive name of the response header to query.
* @param aValue The response header value to set.
*/
setResponseHeader: function Channel_setResponseHeader(aHeader, aValue, aMerge) {
let name = aHeader.toLowerCase();
if (!aValue && !aMerge)
@ -374,10 +355,6 @@ Channel.prototype = {
this._responseHeaders[name] = aValue;
},
/**
* Call this method to visit all response headers.
* @param aVisitor The header visitor.
*/
visitResponseHeaders: function Channel_visitResponseHeaders(aVisitor) {
for (let name in this._responseHeaders) {
let value = this._responseHeaders[name];
@ -391,48 +368,17 @@ Channel.prototype = {
}
},
/* :::::::: nsIRequest ::::::::::::::: */
loadFlags: Ci.nsIRequest.LOAD_NORMAL,
loadGroup: null,
get name() this._uri.spec,
_status: Cr.NS_OK,
get status() this._status,
_isPending: false,
isPending: function () this._isPending,
resume: function () {},
suspend: function () {},
/**
* Cancels this request.
* @param aStatus The reason for cancelling.
*/
cancel: function Channel_cancel(aStatus) {
if (this.canceled)
return;
this._isCanceled = true;
this._status = aStatus;
this._cleanup();
},
/* :::::::: nsIHttpChannelInternal ::::::::::::::: */
documentURI: null,
_isCanceled: false,
get canceled() this._isCanceled,
get canceled() this._canceled,
allowSpdy: false,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel,
Ci.nsIHttpChannel,
Ci.nsIHttpChannelInternal,
Ci.nsIRequest])
};
}
/**
* Parses a given URI and extracts all parameters relevant to this protocol.

View File

@ -103,7 +103,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
; Must be inserted before other macros that use logging
!insertmacro _LoggingCommon
!insertmacro AddDDEHandlerValues
!insertmacro AddDisabledDDEHandlerValues
!insertmacro ChangeMUIHeaderImage
!insertmacro CheckForFilesInUse
!insertmacro CleanUpdatesDir
@ -352,17 +352,15 @@ Section "-Application" APP_IDX
${SetUninstallKeys}
; On install always add the FirefoxHTML and FirefoxURL keys.
; An empty string is used for the 5th param because FirefoxHTML and FirefoxURL
; are not protocol handlers.
; An empty string is used for the 5th param because FirefoxHTML is not a
; protocol handler.
${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
StrCpy $3 "$\"%1$\",,0,0,,,,"
StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} Document" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
"${AppRegName} Document" ""
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
"true"
; The following keys should only be set if we can write to HKLM
${If} $TmpVal == "HKLM"

View File

@ -79,7 +79,7 @@
${GetLongPath} "$0" $0
${EndIf}
${If} "$0" == "$INSTDIR"
${SetStartMenuInternet}
${SetStartMenuInternet} ; Does not use SHCTX
${EndIf}
ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion"
@ -156,12 +156,12 @@
!define PostUpdate "!insertmacro PostUpdate"
!macro SetAsDefaultAppGlobal
${RemoveDeprecatedKeys}
${RemoveDeprecatedKeys} ; Does not use SHCTX
SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM)
${SetHandlers}
${SetStartMenuInternet}
${FixShellIconHandler}
${SetHandlers} ; Uses SHCTX
${SetStartMenuInternet} ; Does not use SHCTX
${FixShellIconHandler} ; Does not use SHCTX
${ShowShortcuts}
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
WriteRegStr HKLM "Software\Clients\StartMenuInternet" "" "$R9"
@ -306,7 +306,7 @@
${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
StrCpy $0 "SOFTWARE\Classes"
StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
; Associate the file handlers with FirefoxHTML
ReadRegStr $6 SHCTX "$0\.htm" ""
@ -340,25 +340,20 @@
WriteRegStr SHCTX "$0\.webm" "" "FirefoxHTML"
${EndIf}
StrCpy $3 "$\"%1$\",,0,0,,,,"
; An empty string is used for the 5th param because FirefoxHTML is not a
; protocol handler
${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} HTML Document" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
"${AppRegName} HTML Document" ""
${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
"true"
; An empty string is used for the 4th & 5th params because the following
; protocol handlers already have a display name and the additional keys
; required for a protocol handler.
${AddDDEHandlerValues} "ftp" "$2" "$8,1" "" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDDEHandlerValues} "http" "$2" "$8,1" "" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDDEHandlerValues} "https" "$2" "$8,1" "" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" ""
${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" ""
${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" ""
!macroend
!define SetHandlers "!insertmacro SetHandlers"
@ -567,8 +562,7 @@
!macro UpdateProtocolHandlers
; Store the command to open the app with an url in a register for easy access.
${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
StrCpy $3 "$\"%1$\",,0,0,,,,"
StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
; Only set the file and protocol handlers if the existing one under HKCR is
; for this install location.
@ -577,32 +571,32 @@
${If} "$R9" == "true"
; An empty string is used for the 5th param because FirefoxHTML is not a
; protocol handler.
${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} HTML Document" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
"${AppRegName} HTML Document" ""
${EndIf}
${IsHandlerForInstallDir} "FirefoxURL" $R9
${If} "$R9" == "true"
${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" \
"${AppRegName} URL" "true"
${EndIf}
; An empty string is used for the 4th & 5th params because the following
; protocol handlers already have a display name and the additional keys
; required for a protocol handler.
${IsHandlerForInstallDir} "ftp" $R9
${If} "$R9" == "true"
${AddDDEHandlerValues} "ftp" "$2" "$8,1" "" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" ""
${EndIf}
${IsHandlerForInstallDir} "http" $R9
${If} "$R9" == "true"
${AddDDEHandlerValues} "http" "$2" "$8,1" "" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" ""
${EndIf}
${IsHandlerForInstallDir} "https" $R9
${If} "$R9" == "true"
${AddDDEHandlerValues} "https" "$2" "$8,1" "" "" \
"${DDEApplication}" "$3" "WWW_OpenURL"
${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" ""
${EndIf}
!macroend
!define UpdateProtocolHandlers "!insertmacro UpdateProtocolHandlers"
@ -1164,11 +1158,13 @@ Function SetAsDefaultAppUser
; b) is not a member of the administrators group and chooses to elevate
${ElevateUAC}
${SetStartMenuInternet}
${SetStartMenuInternet} ; Does not use SHCTX
SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM)
${FixShellIconHandler}
${RemoveDeprecatedKeys}
${FixClassKeys} ; Does not use SHCTX
${FixShellIconHandler} ; Does not use SHCTX
${RemoveDeprecatedKeys} ; Does not use SHCTX
ClearErrors
${GetParameters} $0

View File

@ -92,7 +92,7 @@ Var MaintCertKey
VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
VIAddVersionKey "OriginalFilename" "helper.exe"
!insertmacro AddDDEHandlerValues
!insertmacro AddDisabledDDEHandlerValues
!insertmacro CleanVirtualStore
!insertmacro ElevateUAC
!insertmacro GetLongPath

View File

@ -102,7 +102,7 @@ if [ "$MOZ_SAFE_BROWSING" ]; then
"
fi
if [ "$MOZ_WIDGET_TOOLKIT" = "windows" ]; then
if [ "$MAKENSISU" ]; then
add_makefiles "
browser/installer/windows/Makefile
"

View File

@ -1148,7 +1148,7 @@ toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
/* ::::: fullscreen window controls ::::: */
#TabsToolbar > #window-controls {
#window-controls {
-moz-margin-start: 4px;
}

View File

@ -41,6 +41,7 @@ package @ANDROID_PACKAGE_NAME@;
public interface Assert {
void dumpLog(String message);
void dumpLog(String message, Throwable t);
void setLogFile(String filename);
void setTestName(String testName);

View File

@ -66,6 +66,11 @@ public class FennecMochitestAssert implements Assert {
FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message);
}
/** Write information to a logfile and logcat */
public void dumpLog(String message, Throwable t) {
FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message, t);
}
/** Set the filename used for dumpLog. */
public void setLogFile(String filename) {
FennecNativeDriver.setLogFile(filename);

View File

@ -41,7 +41,6 @@ package @ANDROID_PACKAGE_NAME@;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileReader;
@ -49,6 +48,7 @@ import java.io.FileWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.List;
@ -459,41 +459,48 @@ public class FennecNativeDriver implements Driver {
}
public static void log(LogLevel level, String message) {
log(level, message, null);
}
public static void log(LogLevel level, Throwable t) {
log(level, null, t);
}
public static void log(LogLevel level, String message, Throwable t) {
if (mLogFile == null) {
assert(false);
}
if (level.isEnabled(mLogLevel)) {
File file = new File(mLogFile);
BufferedWriter bw = null;
PrintWriter pw = null;
try {
bw = new BufferedWriter(new FileWriter(mLogFile, true));
bw.write(message);
bw.newLine();
} catch(IOException e) {
pw = new PrintWriter(new FileWriter(mLogFile, true));
if (message != null) {
pw.println(message);
}
if (t != null) {
t.printStackTrace(pw);
}
} catch (IOException ioe) {
Log.e("Robocop", "exception with file writer on: " + mLogFile);
} finally {
try {
if (bw != null) {
bw.flush();
bw.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
pw.close();
}
// PrintWriter doesn't throw IOE but sets an error flag instead,
// so check for that
if (pw.checkError()) {
Log.e("Robocop", "exception with file writer on: " + mLogFile);
}
}
if (level == LogLevel.LOG_LEVEL_INFO) {
Log.i("Robocop", message);
Log.i("Robocop", message, t);
} else if (level == LogLevel.LOG_LEVEL_DEBUG) {
Log.d("Robocop", message);
Log.d("Robocop", message, t);
} else if (level == LogLevel.LOG_LEVEL_WARN) {
Log.w("Robocop", message);
Log.w("Robocop", message, t);
} else if (level == LogLevel.LOG_LEVEL_ERROR) {
Log.e("Robocop", message);
Log.e("Robocop", message, t);
}
}
}

View File

@ -49,6 +49,11 @@ public class FennecTalosAssert implements Assert {
FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message);
}
/** Write information to a logfile and logcat */
public void dumpLog(String message, Throwable t) {
FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message, t);
}
/**
* Set the filename used for dumpLog.
*/

View File

@ -127,8 +127,8 @@ classes.dex: $(_JAVA_TESTS)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(addprefix $(DEPTH)/mobile/android/base/tests/,$(_JAVA_TESTS))
$(DX) --dex --output=$@ classes $(ROBOTIUM_PATH)
robocop.ap_: AndroidManifest.xml
$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -F $@ -J ./
robocop.ap_: AndroidManifest.xml $(TESTPATH)/assets/*
$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./
robocop.apk: robocop.ap_ classes.dex
cp $(TESTPATH)/robocop.ini robocop.ini

View File

@ -265,9 +265,9 @@ build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir, True)
stage1_tool_inst_dir = stage1_dir + '/inst'
stage2_dir = build_dir + '/stage2'
build_one_stage({"CC" : stage1_tool_inst_dir + "/bin/gcc -fgnu89-inline",
"CXX" : stage1_tool_inst_dir + "/bin/g++",
"AR" : stage1_tool_inst_dir + "/bin/ar",
build_one_stage({"PATH" : stage1_tool_inst_dir + "/bin:/bin:/usr/bin",
"CC" : "gcc -fgnu89-inline",
"CXX" : "g++",
"RANLIB" : "true" },
stage2_dir, False)

View File

@ -6319,29 +6319,38 @@ dnl ========================================================
dnl Installer
dnl ========================================================
dnl Abort Windows build if the required major version and
dnl minimum minor version of Unicode NSIS isn't in the path.
dnl minimum minor version of Unicode NSIS isn't in the path
dnl (unless in case of cross compiling, for which Unicode
dnl is not yet sufficient).
if test "$OS_ARCH" = "WINNT"; then
REQ_NSIS_MAJOR_VER=2
MIN_NSIS_MINOR_VER=33
MOZ_PATH_PROGS(MAKENSISU, $MAKENSISU makensisu-2.46 makensisu makensis)
if test -z "$MAKENSISU" -o "$MAKENSISU" = ":"; then
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
if test -n "$MAKENSISU" -a "$MAKENSISU" != ":"; then
AC_MSG_RESULT([yes])
changequote(,)
MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
changequote([,])
if test ! "$MAKENSISU_VER" = ""; then
MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
fi
AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
if test "$MAKENSISU_VER" = "" || \
test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
AC_MSG_RESULT([no])
if test -z "$CROSS_COMPILE"; then
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
else
MAKENSISU=
fi
fi
elif test -z "$CROSS_COMPILE"; then
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
else
MAKENSISU=
fi
changequote(,)
MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
changequote([,])
if test ! "$MAKENSISU_VER" = ""; then
MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
fi
AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
if test "$MAKENSISU_VER" = "" ||
test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
AC_MSG_RESULT([no])
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
fi
AC_MSG_RESULT([yes])
fi
AC_MSG_CHECKING([for tar archiver])
@ -6458,14 +6467,6 @@ MOZ_ARG_DISABLE_BOOL(tests,
ENABLE_TESTS=,
ENABLE_TESTS=1 )
dnl ========================================================
dnl Marionette
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(marionette,
[ --enable-marionette Enable Marionette for remote testing and control],
ENABLE_MARIONETTE=1,
ENABLE_MARIONETTE)
dnl ========================================================
dnl parental controls (for Windows Vista)
dnl ========================================================

View File

@ -19,6 +19,7 @@
* Contributor(s):
* Sid Stamm <sid@mozilla.com>
* Brandon Sterne <bsterne@mozilla.com>
* Ian Melven <imelven@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -301,7 +302,7 @@ ContentSecurityPolicy.prototype = {
var failure = function(aEvt) {
if (req.readyState == 4 && req.status != 200) {
CSPError("Failed to send report to " + reportURI);
CSPError("Failed to send report to " + uris[i]);
}
};
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
@ -313,6 +314,10 @@ ContentSecurityPolicy.prototype = {
req.upload.addEventListener("error", failure, false);
req.upload.addEventListener("abort", failure, false);
// we need to set an nsIChannelEventSink on the XHR object
// so we can tell it to not follow redirects when posting the reports
req.channel.notificationCallbacks = new CSPReportRedirectSink();
req.send(JSON.stringify(report));
CSPdebug("Sent violation report to " + uris[i]);
} catch(e) {
@ -494,4 +499,54 @@ ContentSecurityPolicy.prototype = {
},
};
// The POST of the violation report (if it happens) should not follow
// redirects, per the spec. hence, we implement an nsIChannelEventSink
// with an object so we can tell XHR to abort if a redirect happens.
function CSPReportRedirectSink() {
}
CSPReportRedirectSink.prototype = {
QueryInterface: function requestor_qi(iid) {
if (iid.equals(Ci.nsISupports) ||
iid.equals(Ci.nsIInterfaceRequestor) ||
iid.equals(Ci.nsIChannelEventSink))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
},
// nsIInterfaceRequestor
getInterface: function requestor_gi(iid) {
if (iid.equals(Ci.nsIChannelEventSink))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
// nsIChannelEventSink
asyncOnChannelRedirect: function channel_redirect(oldChannel, newChannel,
flags, callback) {
CSPWarning("Post of violation report to " + oldChannel.URI.asciiSpec +
" failed, as a redirect occurred");
// cancel the old channel so XHR failure callback happens
oldChannel.cancel(Cr.NS_ERROR_ABORT);
// notify an observer that we have blocked the report POST due to a redirect,
// used in testing, do this async since we're in an async call now to begin with
Services.tm.mainThread.dispatch(
function() {
observerSubject = Cc["@mozilla.org/supports-cstring;1"]
.createInstance(Ci.nsISupportsCString);
observerSubject.data = oldChannel.URI.asciiSpec;
Services.obs.notifyObservers(observerSubject,
CSP_VIOLATION_TOPIC,
"denied redirect while sending violation report");
}, Ci.nsIThread.DISPATCH_NORMAL);
// throw to stop the redirect happening
throw Cr.NS_BINDING_REDIRECTED;
}
};
var NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentSecurityPolicy]);

View File

@ -378,3 +378,29 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
static PLDHashOperator
TraceActiveWindowGlobal(const PRUint64& aId, nsGlobalWindow*& aWindow, void* aClosure)
{
if (aWindow->GetDocShell() && aWindow->IsOuterWindow()) {
if (JSObject* global = aWindow->FastGetGlobalJSObject()) {
JSTracer* trc = static_cast<JSTracer *>(aClosure);
JS_CALL_OBJECT_TRACER(trc, global, "active window global");
}
}
return PL_DHASH_NEXT;
}
void
mozilla::dom::TraceBlackJS(JSTracer* aTrc)
{
if (!nsCCUncollectableMarker::sGeneration) {
return;
}
// Mark globals of active windows black.
nsGlobalWindow::WindowByIdTable* windowsById =
nsGlobalWindow::GetWindowsTable();
if (windowsById) {
windowsById->Enumerate(TraceActiveWindowGlobal, aTrc);
}
}

View File

@ -38,6 +38,8 @@
#include "nsIObserver.h"
#include "nsCycleCollectionParticipant.h"
struct JSTracer;
class nsCCUncollectableMarker : public nsIObserver
{
NS_DECL_ISUPPORTS
@ -56,10 +58,10 @@ class nsCCUncollectableMarker : public nsIObserver
return aGeneration && aGeneration == sGeneration;
}
static bool InGeneration(nsCycleCollectionTraversalCallback &cb,
static bool InGeneration(nsCycleCollectionTraversalCallback& aCb,
PRUint32 aGeneration)
{
return InGeneration(aGeneration) && !cb.WantAllTraces();
return InGeneration(aGeneration) && !aCb.WantAllTraces();
}
static PRUint32 sGeneration;
@ -68,3 +70,9 @@ private:
nsCCUncollectableMarker() {}
};
namespace mozilla {
namespace dom {
void TraceBlackJS(JSTracer* aTrc);
}
}

View File

@ -2547,6 +2547,7 @@ void
nsDocument::StopDocumentLoad()
{
if (mParser) {
mParserAborted = true;
mParser->Terminate();
}
}

View File

@ -1188,6 +1188,10 @@ protected:
// our presshell. This is used to handle flush reentry correctly.
bool mInFlush:1;
// Parser aborted. True if the parser of this document was forcibly
// terminated instead of letting it finish at its own pace.
bool mParserAborted:1;
PRUint8 mXMLDeclarationBits;
nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject> *mBoxObjectTable;

View File

@ -1935,7 +1935,8 @@ GK_ATOM(VolumeUp, "VolumeUp")
GK_ATOM(VolumeDown, "VolumeDown")
GK_ATOM(Menu, "Menu")
// Smooth scroll profiles
// Smooth scroll events origins
GK_ATOM(mouseWheel, "mouseWheel") // For discrete wheel events (e.g. not OSX magic mouse)
GK_ATOM(pixels, "pixels")
GK_ATOM(lines, "lines")
GK_ATOM(pages, "pages")

View File

@ -314,42 +314,32 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
mCurrentRequestNeedsResetAnimation = false;
}
// We just loaded all the data we're going to get. If we haven't done an
// initial paint, we want to make sure the image starts decoding for 2
// reasons:
// We just loaded all the data we're going to get. If we're visible and
// haven't done an initial paint (*), we want to make sure the image starts
// decoding immediately, for two reasons:
//
// 1) This image is sitting idle but might need to be decoded as soon as we
// start painting, in which case we've wasted time.
//
// 2) We want to block onload until all visible images are decoded. We do this
// by blocking onload until all in progress decodes get at least one frame
// by blocking onload until all in-progress decodes get at least one frame
// decoded. However, if all the data comes in while painting is suppressed
// (ie, before the initial paint delay is finished), we fire onload without
// doing a paint first. This means that decode-on-draw images don't start
// decoding, so we can't wait for them to finish. See bug 512435.
//
// (*) IsPaintingSuppressed returns false if we haven't gotten the initial
// reflow yet, so we have to test !DidInitialReflow || IsPaintingSuppressed.
// It's possible for painting to be suppressed for reasons other than the
// initial paint delay (for example, being in the bfcache), but we probably
// aren't loading images in those situations.
// We can only do this if we have a presshell
nsIDocument* doc = GetOurDocument();
nsIPresShell* shell = doc ? doc->GetShell() : nsnull;
if (shell) {
// We need to figure out whether to kick off decoding
bool doRequestDecode = false;
if (shell && shell->IsVisible() &&
(!shell->DidInitialReflow() || shell->IsPaintingSuppressed())) {
// If we haven't got the initial reflow yet, IsPaintingSuppressed actually
// returns false
if (!shell->DidInitialReflow())
doRequestDecode = true;
// Figure out if painting is suppressed. Note that it's possible for painting
// to be suppressed for reasons other than the initial paint delay (for
// example - being in the bfcache), but we probably aren't loading images in
// those situations.
if (shell->IsPaintingSuppressed())
doRequestDecode = true;
// If we're requesting a decode, do it
if (doRequestDecode)
mCurrentRequest->RequestDecode();
mCurrentRequest->RequestDecode();
}
// Fire the appropriate DOM event.

View File

@ -2768,10 +2768,13 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
// Create our listener
nsCOMPtr<nsIStreamListener> listener = this;
if (mState & XML_HTTP_REQUEST_MULTIPART) {
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 1);
listener = new nsMultipartProxyListener(listener);
if (!listener) {
return NS_ERROR_OUT_OF_MEMORY;
}
} else {
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 0);
}
// Blocking gets are common enough out of XHR that we should mark

View File

@ -572,6 +572,12 @@ _TEST_FILES2 = \
test_bug737612.html \
test_bug738108.html \
test_bug366944.html \
test_bug650386_redirect_301.html \
test_bug650386_redirect_302.html \
test_bug650386_redirect_303.html \
test_bug650386_redirect_307.html \
file_bug650386_content.sjs \
file_bug650386_report.sjs \
$(NULL)
_CHROME_FILES = \

View File

@ -0,0 +1,37 @@
// SJS file for tests for bug650386, serves file_bug650386_content.html
// with a CSP that will trigger a violation and that will report it
// to file_bug650386_report.sjs
//
// This handles 301, 302, 303 and 307 redirects. The HTTP status code
// returned/type of redirect to do comes from the query string
// parameter passed in from the test_bug650386_* files and then also
// uses that value in the report-uri parameter of the CSP
function handleRequest(request, response) {
response.setHeader("Cache-Control", "no-cache", false);
// this gets used in the CSP as part of the report URI.
var redirect = request.queryString;
if (redirect < 301 || (redirect > 303 && redirect <= 306) || redirect > 307) {
// if we somehow got some bogus redirect code here,
// do a 302 redirect to the same URL as the report URI
// redirects to - this will fail the test.
var loc = "http://example.com/some/fake/path";
response.setStatusLine("1.1", 302, "Found");
response.setHeader("Location", loc, false);
return;
}
var csp = "default-src \'self\';report-uri http://mochi.test:8888/tests/content/base/test/file_bug650386_report.sjs?" + redirect;
response.setHeader("X-Content-Security-Policy", csp, false);
// the actual file content.
// this image load will (intentionally) fail due to the CSP policy of default-src: 'self'
// specified by the CSP string above.
var content = "<!DOCTYPE HTML><html><body><img src = \"http://some.other.domain.example.com\"></body></html>";
response.write(content);
return;
}

View File

@ -0,0 +1,16 @@
// SJS file for tests for bug650386, this serves as CSP violation report target
// and issues a redirect, to make sure the browser does not post to the target
// of the redirect, per CSP spec.
// This handles 301, 302, 303 and 307 redirects. The HTTP status code
// returned/type of redirect to do comes from the query string
// parameter
function handleRequest(request, response) {
response.setHeader("Cache-Control", "no-cache", false);
var redirect = request.queryString;
var loc = "http://example.com/some/fake/path";
response.setStatusLine("1.1", redirect, "Found");
response.setHeader("Location", loc, false);
return;
}

View File

@ -0,0 +1,78 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
Test that CSP violation reports are not sent when a 301 redirect is encountered
-->
<head>
<title>Test for Bug 650386</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id = "content_iframe"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 650386 **/
// This is used to watch the redirect of the report POST get blocked
function examiner() {
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
SpecialPowers.addObserver(this, "http-on-modify-request", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
// subject should be an nsURI
if(!SpecialPowers.can_QI(subject))
return;
if (topic === "http-on-modify-request") {
// this is used to fail the test - if we see the POST to the target of the redirect
// we know this is a fail
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
if (asciiSpec == "http://example.com/some/fake/path")
window.done(false);
}
if(topic === "csp-on-violate-policy") {
// something was blocked, but we are looking specifically for the redirect being blocked
if (data == "denied redirect while sending violation report")
window.done(true);
}
},
// must eventually call this to remove the listener,
// or mochitests might get borked.
remove: function() {
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
SpecialPowers.removeObserver(this, "http-on-modify-request");
}
}
window.examiner = new examiner();
// result == true if we saw the redirect blocked notify, false if we saw the post
// to the redirect target go out
window.done = function(result) {
ok(result, "a 301 redirect when posting violation report should be blocked");
// clean up observers and finish the test
window.examiner.remove();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
// save this for last so that our listeners are registered.
document.getElementById('content_iframe').src = 'file_bug650386_content.sjs?301';
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,78 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
Test that CSP violation reports are not sent when a 302 redirect is encountered
-->
<head>
<title>Test for Bug 650386</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id = "content_iframe"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 650386 **/
// This is used to watch the redirect of the report POST get blocked
function examiner() {
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
SpecialPowers.addObserver(this, "http-on-modify-request", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
// subject should be an nsURI
if(!SpecialPowers.can_QI(subject))
return;
if (topic === "http-on-modify-request") {
// this is used to fail the test - if we see the POST to the target of the redirect
// we know this is a fail
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
if (asciiSpec == "http://example.com/some/fake/path")
window.done(false);
}
if(topic === "csp-on-violate-policy") {
// something was blocked, but we are looking specifically for the redirect being blocked
if (data == "denied redirect while sending violation report")
window.done(true);
}
},
// must eventually call this to remove the listener,
// or mochitests might get borked.
remove: function() {
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
SpecialPowers.removeObserver(this, "http-on-modify-request");
}
}
window.examiner = new examiner();
// result == true if we saw the redirect blocked notify, false if we saw the post
// to the redirect target go out
window.done = function(result) {
ok(result, "a 302 redirect when posting violation report should be blocked");
// clean up observers and finish the test
window.examiner.remove();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
// save this for last so that our listeners are registered.
document.getElementById('content_iframe').src = 'file_bug650386_content.sjs?302';
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,78 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
Test that CSP violation reports are not sent when a 303 redirect is encountered
-->
<head>
<title>Test for Bug 650386</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id = "content_iframe"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 650386 **/
// This is used to watch the redirect of the report POST get blocked
function examiner() {
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
SpecialPowers.addObserver(this, "http-on-modify-request", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
// subject should be an nsURI
if(!SpecialPowers.can_QI(subject))
return;
if (topic === "http-on-modify-request") {
// this is used to fail the test - if we see the POST to the target of the redirect
// we know this is a fail
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
if (asciiSpec == "http://example.com/some/fake/path")
window.done(false);
}
if(topic === "csp-on-violate-policy") {
// something was blocked, but we are looking specifically for the redirect being blocked
if (data == "denied redirect while sending violation report")
window.done(true);
}
},
// must eventually call this to remove the listener,
// or mochitests might get borked.
remove: function() {
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
SpecialPowers.removeObserver(this, "http-on-modify-request");
}
}
window.examiner = new examiner();
// result == true if we saw the redirect blocked notify, false if we saw the post
// to the redirect target go out
window.done = function(result) {
ok(result, "a 303 redirect when posting violation report should be blocked");
// clean up observers and finish the test
window.examiner.remove();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
// save this for last so that our listeners are registered.
document.getElementById('content_iframe').src = 'file_bug650386_content.sjs?303';
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,78 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
Test that CSP violation reports are not sent when a 307 redirect is encountered
-->
<head>
<title>Test for Bug 650386</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id = "content_iframe"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 650386 **/
// This is used to watch the redirect of the report POST get blocked
function examiner() {
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
SpecialPowers.addObserver(this, "http-on-modify-request", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
// subject should be an nsURI
if(!SpecialPowers.can_QI(subject))
return;
if (topic === "http-on-modify-request") {
// this is used to fail the test - if we see the POST to the target of the redirect
// we know this is a fail
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
if (asciiSpec == "http://example.com/some/fake/path")
window.done(false);
}
if(topic === "csp-on-violate-policy") {
// something was blocked, but we are looking specifically for the redirect being blocked
if (data == "denied redirect while sending violation report")
window.done(true);
}
},
// must eventually call this to remove the listener,
// or mochitests might get borked.
remove: function() {
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
SpecialPowers.removeObserver(this, "http-on-modify-request");
}
}
window.examiner = new examiner();
// result == true if we saw the redirect blocked notify, false if we saw the post
// to the redirect target go out
window.done = function(result) {
ok(result, "a 307 redirect when posting violation report should be blocked");
// clean up observers and finish the test
window.examiner.remove();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
// save this for last so that our listeners are registered.
document.getElementById('content_iframe').src = 'file_bug650386_content.sjs?307';
</script>
</pre>
</body>
</html>

View File

@ -2695,7 +2695,8 @@ nsEventStateManager::DoScrollText(nsIFrame* aTargetFrame,
nsMouseScrollEvent* aMouseEvent,
nsIScrollableFrame::ScrollUnit aScrollQuantity,
bool aAllowScrollSpeedOverride,
nsQueryContentEvent* aQueryEvent)
nsQueryContentEvent* aQueryEvent,
nsIAtom *aOrigin)
{
nsIScrollableFrame* frameToScroll = nsnull;
nsIFrame* scrollFrame = aTargetFrame;
@ -2857,7 +2858,7 @@ nsEventStateManager::DoScrollText(nsIFrame* aTargetFrame,
nsIntPoint overflow;
frameToScroll->ScrollBy(nsIntPoint(scrollX, scrollY), aScrollQuantity,
mode, &overflow);
mode, &overflow, aOrigin);
aMouseEvent->scrollOverflow = isHorizontal ? overflow.x : overflow.y;
return NS_OK;
}
@ -2867,7 +2868,7 @@ nsEventStateManager::DoScrollText(nsIFrame* aTargetFrame,
aTargetFrame->PresContext()->FrameManager()->GetRootFrame());
if (newFrame)
return DoScrollText(newFrame, aMouseEvent, aScrollQuantity,
aAllowScrollSpeedOverride, aQueryEvent);
aAllowScrollSpeedOverride, aQueryEvent, aOrigin);
}
aMouseEvent->scrollOverflow = numLines;
@ -3213,7 +3214,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
switch (action) {
case MOUSE_SCROLL_N_LINES:
DoScrollText(aTargetFrame, msEvent, nsIScrollableFrame::LINES,
useSysNumLines);
useSysNumLines, nsnull, nsGkAtoms::mouseWheel);
break;
case MOUSE_SCROLL_PAGE:
@ -3222,8 +3223,11 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
break;
case MOUSE_SCROLL_PIXELS:
DoScrollText(aTargetFrame, msEvent, nsIScrollableFrame::DEVICE_PIXELS,
false);
{
bool fromLines = msEvent->scrollFlags & nsMouseScrollEvent::kFromLines;
DoScrollText(aTargetFrame, msEvent, nsIScrollableFrame::DEVICE_PIXELS,
false, nsnull, (fromLines ? nsGkAtoms::mouseWheel : nsnull));
}
break;
case MOUSE_SCROLL_HISTORY:

View File

@ -353,7 +353,8 @@ protected:
nsMouseScrollEvent* aMouseEvent,
nsIScrollableFrame::ScrollUnit aScrollQuantity,
bool aAllowScrollSpeedOverride,
nsQueryContentEvent* aQueryEvent = nsnull);
nsQueryContentEvent* aQueryEvent = nsnull,
nsIAtom *aOrigin = nsnull);
void DoScrollHistory(PRInt32 direction);
void DoScrollZoom(nsIFrame *aTargetFrame, PRInt32 adjustment);
nsresult GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv);

View File

@ -134,6 +134,7 @@
#include "nsMimeTypes.h"
#include "nsIRequest.h"
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5Parser.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -1558,6 +1559,7 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
// resetting the document.
mSecurityInfo = securityInfo;
mParserAborted = false;
bool loadAsHtml5 = nsHtml5Module::sEnabled;
if (loadAsHtml5) {
mParser = nsHtml5Module::NewHtml5Parser();
@ -1644,8 +1646,8 @@ nsHTMLDocument::Close()
}
++mWriteLevel;
nsresult rv = mParser->Parse(EmptyString(), nsnull,
GetContentTypeInternal(), true);
nsresult rv = (static_cast<nsHtml5Parser*>(mParser.get()))->Parse(
EmptyString(), nsnull, GetContentTypeInternal(), true);
--mWriteLevel;
// XXX Make sure that all the document.written content is
@ -1701,6 +1703,13 @@ nsHTMLDocument::WriteCommon(JSContext *cx,
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
if (mParserAborted) {
// Hixie says aborting the parser doesn't undefine the insertion point.
// However, since we null out mParser in that case, we track the
// theoretically defined insertion point using mParserAborted.
return NS_OK;
}
nsresult rv = NS_OK;
void *key = GenerateParserKey();
@ -1764,13 +1773,11 @@ nsHTMLDocument::WriteCommon(JSContext *cx,
// since the concatenation of strings costs more than we like. And
// why pay that price when we don't need to?
if (aNewlineTerminate) {
rv = mParser->Parse(aText + new_line,
key, GetContentTypeInternal(),
false);
rv = (static_cast<nsHtml5Parser*>(mParser.get()))->Parse(
aText + new_line, key, GetContentTypeInternal(), false);
} else {
rv = mParser->Parse(aText,
key, GetContentTypeInternal(),
false);
rv = (static_cast<nsHtml5Parser*>(mParser.get()))->Parse(
aText, key, GetContentTypeInternal(), false);
}
--mWriteLevel;

View File

@ -8348,13 +8348,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
sameExceptHashes && !newHash.IsEmpty());
if (doShortCircuitedLoad) {
// If our load group contains a LOAD_DOCUMENT_URI request with a
// channel which doesn't match our document's channel, cancel it.
//
// That is, a short-circuited load will cancel a non-short-circuited
// load of a different document.
StopOutstandingOtherDocumentLoad();
// Save the current URI; we need it if we fire a hashchange later.
nsCOMPtr<nsIURI> oldURI = mCurrentURI;
@ -8654,47 +8647,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
return rv;
}
// If our load group contains a LOAD_DOCUMENT_URI channel that's not our
// document's channel, cancel it.
void
nsDocShell::StopOutstandingOtherDocumentLoad()
{
nsCOMPtr<nsIChannel> docChannel = GetCurrentDocChannel();
if (!docChannel || !mLoadGroup) {
return;
}
nsCOMPtr<nsISimpleEnumerator> requests;
mLoadGroup->GetRequests(getter_AddRefs(requests));
if (!requests) {
return;
}
while (true) {
bool hasMoreElements = false;
requests->HasMoreElements(&hasMoreElements);
if (!hasMoreElements) {
break;
}
nsCOMPtr<nsISupports> next;
requests->GetNext(getter_AddRefs(next));
nsCOMPtr<nsIChannel> channel = do_QueryInterface(next);
if (!channel) {
continue;
}
nsLoadFlags flags;
channel->GetLoadFlags(&flags);
// As promised, cancel the channel if it's loading a different document.
if ((flags & nsIChannel::LOAD_DOCUMENT_URI) && channel != docChannel) {
channel->Cancel(NS_BINDING_ABORTED);
}
}
}
nsIPrincipal*
nsDocShell::GetInheritedPrincipal(bool aConsiderCurrentDocument)
{

View File

@ -672,11 +672,6 @@ protected:
nsresult EnsureCommandHandler();
nsIChannel* GetCurrentDocChannel();
// If our load group contains a LOAD_DOCUMENT_URI channel that's not our
// document's channel, cancel it.
void StopOutstandingOtherDocumentLoad();
protected:
// Override the parent setter from nsDocLoader
virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);

View File

@ -1153,7 +1153,7 @@ Navigator::GetMozBluetooth(nsIDOMBluetoothAdapter** aBluetooth)
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
mBluetooth = new bluetooth::BluetoothAdapter();
mBluetooth = new bluetooth::BluetoothAdapter(window);
bluetooth = mBluetooth;
}

View File

@ -943,16 +943,17 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
nsIScriptGlobalObject *global = context->GetGlobalObject();
// XXX should we check for sysprin instead of a chrome window, to make
// XXX components be covered by the chrome pref instead of the content one?
nsCOMPtr<nsIDOMWindow> contentWindow(do_QueryInterface(global));
nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(global));
bool useMethodJIT = Preferences::GetBool(chromeWindow ?
bool useMethodJIT = Preferences::GetBool(chromeWindow || !contentWindow ?
js_methodjit_chrome_str :
js_methodjit_content_str);
bool usePCCounts = Preferences::GetBool(chromeWindow ?
bool usePCCounts = Preferences::GetBool(chromeWindow || !contentWindow ?
js_pccounts_chrome_str :
js_pccounts_content_str);
bool useMethodJITAlways = Preferences::GetBool(js_methodjit_always_str);
bool useTypeInference = !chromeWindow && Preferences::GetBool(js_typeinfer_str);
bool useTypeInference = !chromeWindow && contentWindow && Preferences::GetBool(js_typeinfer_str);
bool useHardening = Preferences::GetBool(js_jit_hardening_str);
nsCOMPtr<nsIXULRuntime> xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
if (xr) {
@ -992,7 +993,7 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
// javascript.options.strict.debug is true
bool strictDebug = Preferences::GetBool(js_strict_debug_option_str);
if (strictDebug && (newDefaultJSOptions & JSOPTION_STRICT) == 0) {
if (chromeWindow)
if (chromeWindow || !contentWindow)
newDefaultJSOptions |= JSOPTION_STRICT;
}
#endif
@ -2746,7 +2747,7 @@ nsJSContext::InitClasses(JSObject* aGlobalObj)
JSAutoRequest ar(mContext);
::JS_SetOptions(mContext, mDefaultJSOptions);
JSOptionChangedCallback(js_options_dot_str, this);
// Attempt to initialize profiling functions
::JS_DefineProfilingFunctions(mContext, aGlobalObj);

View File

@ -85,6 +85,7 @@ nsStructuredCloneContainer::InitFromVariant(nsIVariant *aData, JSContext *aCx)
JSAutoRequest ar(aCx);
JSAutoEnterCompartment ac;
NS_ENSURE_STATE(ac.enter(aCx, JS_GetGlobalObject(aCx)));
JS_WrapValue(aCx, &jsData);
nsCxPusher cxPusher;
cxPusher.Push(aCx);

View File

@ -4,13 +4,33 @@
* 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 "BluetoothAdapter.h"
#include "nsDOMClassInfo.h"
#include "nsDOMEvent.h"
#include "nsThreadUtils.h"
#include "nsXPCOMCIDInternal.h"
#include "mozilla/LazyIdleThread.h"
#include "mozilla/Util.h"
#include <dlfcn.h>
#include "BluetoothAdapter.h"
static void
FireEnabled(bool aResult, nsIDOMDOMRequest* aDomRequest)
{
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
if (!rs) {
NS_WARNING("No DOMRequest Service!");
return;
}
mozilla::DebugOnly<nsresult> rv = aResult ?
rs->FireSuccess(aDomRequest, JSVAL_VOID) :
rs->FireError(aDomRequest,
NS_LITERAL_STRING("Bluetooth firmware loading failed"));
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Bluetooth firmware loading failed");
}
USING_BLUETOOTH_NAMESPACE
@ -67,11 +87,16 @@ static bool EnsureBluetoothInit() {
class ToggleBtResultTask : public nsRunnable
{
public:
ToggleBtResultTask(nsRefPtr<BluetoothAdapter>& adapterPtr, bool result)
: mResult(result)
ToggleBtResultTask(nsRefPtr<BluetoothAdapter>& adapterPtr,
nsCOMPtr<nsIDOMDOMRequest>& req,
bool enabled,
bool result)
: mResult(result),
mEnabled(enabled)
{
MOZ_ASSERT(!NS_IsMainThread());
mDOMRequest.swap(req);
mAdapterPtr.swap(adapterPtr);
}
@ -79,29 +104,35 @@ class ToggleBtResultTask : public nsRunnable
{
MOZ_ASSERT(NS_IsMainThread());
if (!mResult) {
//TODO:Bug-731361
NS_WARNING("BT firmware loading fails.\n");
// Update bt power status to BluetoothAdapter only if loading bluetooth
// firmware succeeds.
if (mResult) {
mAdapterPtr->SetEnabledInternal(mEnabled);
}
FireEnabled(mResult, mDOMRequest);
//mAdapterPtr must be null before returning to prevent the background
//thread from racing to release it during the destruction of this runnable.
mAdapterPtr->FirePowered();
mAdapterPtr = nsnull;
mDOMRequest = nsnull;
return NS_OK;
}
private:
nsRefPtr<BluetoothAdapter> mAdapterPtr;
nsCOMPtr<nsIDOMDOMRequest> mDOMRequest;
bool mEnabled;
bool mResult;
};
class ToggleBtTask : public nsRunnable
{
public:
ToggleBtTask(bool onOff, BluetoothAdapter* adapterPtr)
: mOnOff(onOff),
ToggleBtTask(bool enabled, nsIDOMDOMRequest* req, BluetoothAdapter* adapterPtr)
: mEnabled(enabled),
mDOMRequest(req),
mAdapterPtr(adapterPtr)
{
MOZ_ASSERT(NS_IsMainThread());
@ -111,23 +142,36 @@ class ToggleBtTask : public nsRunnable
{
MOZ_ASSERT(!NS_IsMainThread());
bool result;
#ifdef MOZ_WIDGET_GONK
// Platform specific check for gonk until object is divided in
// different implementations per platform. Linux doesn't require
// bluetooth firmware loading, but code should work otherwise.
if(!EnsureBluetoothInit()) {
NS_ERROR("Failed to load bluedroid library.\n");
return NS_ERROR_FAILURE;
}
bool result;
// return 1 if it's enabled, 0 if it's disabled, and -1 on error
int isEnabled = sBluedroidFunctions.bt_is_enabled();
//Toggle BT here
if (mOnOff) {
result = sBluedroidFunctions.bt_enable();
if ((isEnabled == 1 && mEnabled) || (isEnabled == 0 && !mEnabled)) {
result = true;
} else if (isEnabled < 0) {
result = false;
} else if (mEnabled) {
result = (sBluedroidFunctions.bt_enable() == 0) ? true : false;
} else {
result = sBluedroidFunctions.bt_disable();
result = (sBluedroidFunctions.bt_disable() == 0) ? true : false;
}
#else
result = true;
NS_WARNING("No bluetooth support in this build configuration, faking a success event instead");
#endif
// Create a result thread and pass it to Main Thread,
nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(mAdapterPtr, result);
nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(mAdapterPtr, mDOMRequest, mEnabled, result);
if (NS_FAILED(NS_DispatchToMainThread(resultRunnable))) {
NS_WARNING("Failed to dispatch to main thread!");
@ -137,8 +181,9 @@ class ToggleBtTask : public nsRunnable
}
private:
bool mOnOff;
bool mEnabled;
nsRefPtr<BluetoothAdapter> mAdapterPtr;
nsCOMPtr<nsIDOMDOMRequest> mDOMRequest;
};
DOMCI_DATA(BluetoothAdapter, BluetoothAdapter)
@ -147,12 +192,12 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(powered)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(enabled)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(powered)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(enabled)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
@ -163,77 +208,43 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
BluetoothAdapter::BluetoothAdapter()
: mPower(false)
BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow *aWindow)
{
BindToOwner(aWindow);
}
NS_IMETHODIMP
BluetoothAdapter::GetPower(bool* aPower)
BluetoothAdapter::SetEnabled(bool aEnabled, nsIDOMDOMRequest** aDomRequest)
{
#ifdef MOZ_WIDGET_GONK
if(!EnsureBluetoothInit()) {
NS_ERROR("Failed to load bluedroid library.\n");
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
if (!rs) {
NS_ERROR("No DOMRequest Service!");
return NS_ERROR_FAILURE;
}
*aPower = sBluedroidFunctions.bt_is_enabled();
#else
*aPower = mPower;
#endif
return NS_OK;
}
NS_IMETHODIMP
BluetoothAdapter::SetPower(bool aPower)
{
#ifdef MOZ_WIDGET_GONK
// Platform specific check for gonk until object is divided in
// different implementations per platform. Linux doesn't require
// bluetooth firmware loading, but code should work otherwise.
if(!EnsureBluetoothInit()) {
NS_ERROR("Failed to load bluedroid library.\n");
return NS_ERROR_FAILURE;
}
#endif
if (mPower != aPower) {
mPower = aPower;
#ifdef MOZ_WIDGET_GONK
return ToggleBluetoothAsync();
#endif
}
return NS_OK;
}
nsresult
BluetoothAdapter::ToggleBluetoothAsync()
{
nsCOMPtr<nsIDOMDOMRequest> request;
nsresult rv = rs->CreateRequest(GetOwner(), getter_AddRefs(request));
NS_ENSURE_SUCCESS(rv, rv);
if (!mToggleBtThread) {
mToggleBtThread = new LazyIdleThread(15000);
}
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(mPower, this);
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(aEnabled, request, this);
return mToggleBtThread->Dispatch(r, NS_DISPATCH_NORMAL);
}
nsresult
BluetoothAdapter::FirePowered()
{
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
nsresult rv = event->InitEvent(NS_LITERAL_STRING("powered"), false, false);
rv = mToggleBtThread->Dispatch(r, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
rv = event->SetTrusted(true);
NS_ENSURE_SUCCESS(rv, rv);
bool dummy;
rv = DispatchEvent(event, &dummy);
NS_ENSURE_SUCCESS(rv, rv);
request.forget(aDomRequest);
return NS_OK;
}
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, powered)
NS_IMETHODIMP
BluetoothAdapter::GetEnabled(bool* aEnabled)
{
*aEnabled = mEnabled;
return NS_OK;
}

View File

@ -10,6 +10,7 @@
#include "BluetoothCommon.h"
#include "nsDOMEventTargetHelper.h"
#include "nsIDOMBluetoothAdapter.h"
#include "nsIDOMDOMRequest.h"
class nsIEventTarget;
@ -27,19 +28,19 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
BluetoothAdapter();
BluetoothAdapter(nsPIDOMWindow*);
nsresult FirePowered();
inline void SetEnabledInternal(bool aEnabled) {mEnabled = aEnabled;}
protected:
bool mPower;
bool mEnabled;
NS_DECL_EVENT_HANDLER(powered)
NS_DECL_EVENT_HANDLER(enabled)
private:
nsCOMPtr<nsIEventTarget> mToggleBtThread;
nsresult ToggleBluetoothAsync();
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -6,12 +6,13 @@
#include "nsIDOMEventTarget.idl"
interface nsIDOMDOMRequest;
interface nsIDOMEventListener;
[scriptable, builtinclass, uuid(3dbaa9f4-5c93-11e1-8592-ff9bfcc3ab4b)]
[scriptable, builtinclass, uuid(ac288eab-dcdb-4f6a-b94d-6c0e286d6a73)]
interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
{
attribute boolean power;
readonly attribute bool enabled;
attribute nsIDOMEventListener onpowered;
nsIDOMDOMRequest setEnabled(in boolean enabled);
};

View File

@ -344,6 +344,13 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBKeyRange)
DOMCI_DATA(IDBKeyRange, IDBKeyRange)
IDBKeyRange::~IDBKeyRange()
{
if (mRooted) {
NS_DROP_JS_OBJECTS(this, IDBKeyRange);
}
}
NS_IMETHODIMP
IDBKeyRange::GetLower(JSContext* aCx,
jsval* aLower)

View File

@ -170,7 +170,7 @@ public:
}
protected:
~IDBKeyRange() { }
~IDBKeyRange();
Key mLower;
Key mUpper;

View File

@ -1318,8 +1318,6 @@ nsDOMStorage::nsDOMStorage()
: mStorageType(nsPIDOMStorage::Unknown)
, mEventBroadcaster(nsnull)
{
mSecurityChecker = this;
if (XRE_GetProcessType() != GeckoProcessType_Default)
mStorageImpl = new StorageChild(this);
else
@ -1328,10 +1326,9 @@ nsDOMStorage::nsDOMStorage()
nsDOMStorage::nsDOMStorage(nsDOMStorage& aThat)
: mStorageType(aThat.mStorageType)
, mPrincipal(aThat.mPrincipal)
, mEventBroadcaster(nsnull)
{
mSecurityChecker = this;
if (XRE_GetProcessType() != GeckoProcessType_Default) {
StorageChild* other = static_cast<StorageChild*>(aThat.mStorageImpl.get());
mStorageImpl = new StorageChild(this, *other);
@ -1382,6 +1379,7 @@ nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &
NS_ENSURE_SUCCESS(rv, rv);
mDocumentURI = aDocumentURI;
mPrincipal = aPrincipal;
mStorageType = SessionStorage;
@ -1397,6 +1395,7 @@ nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aD
NS_ENSURE_SUCCESS(rv, rv);
mDocumentURI = aDocumentURI;
mPrincipal = aPrincipal;
mStorageType = LocalStorage;
@ -1495,8 +1494,7 @@ nsDOMStorage::CacheStoragePermissions()
nsresult rv = ssm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
NS_ENSURE_SUCCESS(rv, false);
NS_ASSERTION(mSecurityChecker, "Has non-null mSecurityChecker");
return mSecurityChecker->CanAccess(subjectPrincipal);
return CanAccess(subjectPrincipal);
}
// static
@ -1729,17 +1727,17 @@ nsDOMStorage::CanAccessSystem(nsIPrincipal *aPrincipal)
bool
nsDOMStorage::CanAccess(nsIPrincipal *aPrincipal)
{
// Allow C++/system callers to access the storage
if (CanAccessSystem(aPrincipal))
// Allow C++ callers to access the storage
if (!aPrincipal)
return true;
nsCAutoString domain;
nsCOMPtr<nsIURI> unused;
nsresult rv = GetPrincipalURIAndHost(aPrincipal,
getter_AddRefs(unused), domain);
NS_ENSURE_SUCCESS(rv, false);
// Allow more powerful principals (e.g. system) to access the storage
bool subsumes;
nsresult rv = aPrincipal->SubsumesIgnoringDomain(mPrincipal, &subsumes);
if (NS_FAILED(rv))
return false;
return domain.Equals(mStorageImpl->mDomain);
return subsumes;
}
nsPIDOMStorage::nsDOMStorageType
@ -1797,7 +1795,6 @@ nsDOMStorage2::nsDOMStorage2()
nsDOMStorage2::nsDOMStorage2(nsDOMStorage2& aThat)
{
mStorage = new nsDOMStorage(*aThat.mStorage.get());
mStorage->mSecurityChecker = mStorage;
mPrincipal = aThat.mPrincipal;
}
@ -1808,7 +1805,6 @@ nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring
if (!mStorage)
return NS_ERROR_OUT_OF_MEMORY;
mStorage->mSecurityChecker = this;
mPrincipal = aPrincipal;
mDocumentURI = aDocumentURI;
@ -1822,7 +1818,6 @@ nsDOMStorage2::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &a
if (!mStorage)
return NS_ERROR_OUT_OF_MEMORY;
mStorage->mSecurityChecker = this;
mPrincipal = aPrincipal;
mDocumentURI = aDocumentURI;
@ -1892,20 +1887,7 @@ nsDOMStorage2::Principal()
bool
nsDOMStorage2::CanAccess(nsIPrincipal *aPrincipal)
{
if (mStorage->mSecurityChecker != this)
return mStorage->mSecurityChecker->CanAccess(aPrincipal);
// Allow C++ callers to access the storage
if (!aPrincipal)
return true;
// Allow more powerful principals (e.g. system) to access the storage
bool subsumes;
nsresult rv = aPrincipal->SubsumesIgnoringDomain(mPrincipal, &subsumes);
if (NS_FAILED(rv))
return false;
return subsumes;
return mStorage->CanAccess(aPrincipal);
}
nsPIDOMStorage::nsDOMStorageType

View File

@ -419,7 +419,7 @@ public:
nsDOMStorageType mStorageType;
friend class nsIDOMStorage2;
nsPIDOMStorage* mSecurityChecker;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsPIDOMStorage* mEventBroadcaster;
};

View File

@ -142,8 +142,8 @@ function RadioInterfaceLayer() {
this.worker.onmessage = this.onmessage.bind(this);
debug("Starting Worker\n");
this.radioState = {
radioState: null,
cardState: null,
radioState: RIL.GECKO_RADIOSTATE_UNAVAILABLE,
cardState: RIL.GECKO_CARDSTATE_UNAVAILABLE,
connected: null,
roaming: null,
signalStrength: null,
@ -194,15 +194,15 @@ RadioInterfaceLayer.prototype = {
// This one will handle its own notifications.
this.handleEnumerateCalls(message.calls);
break;
case "registrationstatechange":
this.updateDataConnection(message.registrationState);
case "voiceregistrationstatechange":
this.updateDataConnection(message.voiceRegistrationState);
break;
case "gprsregistrationstatechange":
let state = message.gprsRegistrationState;
case "dataregistrationstatechange":
let state = message.dataRegistrationState;
this.updateDataConnection(state);
//TODO for simplicity's sake, for now we only look at
// gprsRegistrationState for the radio registration state.
// dataRegistrationState for the radio registration state.
if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
this.resetRadioState();
@ -282,6 +282,9 @@ RadioInterfaceLayer.prototype = {
case "siminfo":
this.radioState.msisdn = message.msisdn;
break;
case "error":
debug("Received error message: " + JSON.stringify(message));
break;
default:
throw new Error("Don't know about this message type: " + message.type);
}
@ -1083,7 +1086,8 @@ let RILNetworkInterface = {
dataCallStateChanged: function dataCallStateChanged(cid, interfaceName, callState) {
if (this.connecting &&
callState == RIL.GECKO_NETWORK_STATE_CONNECTING) {
(callState == RIL.GECKO_NETWORK_STATE_CONNECTING ||
callState == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
this.connecting = false;
this.cid = cid;
this.name = interfaceName;

View File

@ -57,8 +57,8 @@ const REQUEST_CONFERENCE = 16;
const REQUEST_UDUB = 17;
const REQUEST_LAST_CALL_FAIL_CAUSE = 18;
const REQUEST_SIGNAL_STRENGTH = 19;
const REQUEST_REGISTRATION_STATE = 20;
const REQUEST_GPRS_REGISTRATION_STATE = 21;
const REQUEST_VOICE_REGISTRATION_STATE = 20;
const REQUEST_DATA_REGISTRATION_STATE = 21;
const REQUEST_OPERATOR = 22;
const REQUEST_RADIO_POWER = 23;
const REQUEST_DTMF = 24;
@ -114,7 +114,7 @@ const REQUEST_SET_PREFERRED_NETWORK_TYPE = 73;
const REQUEST_GET_PREFERRED_NETWORK_TYPE = 74;
const REQUEST_GET_NEIGHBORING_CELL_IDS = 75;
const REQUEST_SET_LOCATION_UPDATES = 76;
const REQUEST_CDMA_SET_SUBSCRIPTION = 77;
const REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE = 77;
const REQUEST_CDMA_SET_ROAMING_PREFERENCE = 78;
const REQUEST_CDMA_QUERY_ROAMING_PREFERENCE = 79;
const REQUEST_SET_TTY_MODE = 80;
@ -141,6 +141,28 @@ const REQUEST_GET_SMSC_ADDRESS = 100;
const REQUEST_SET_SMSC_ADDRESS = 101;
const REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
const REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
const REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104;
const REQUEST_ISIM_AUTHENTICATION = 105;
const REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106;
const REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
// Akami/Maguro specific parcel types.
const REQUEST_VOICE_RADIO_TECH = 105;
const REQUEST_IMS_REGISTRATION_STATE = 106;
const REQUEST_IMS_SEND_SMS = 107;
const REQUEST_GET_DATA_CALL_PROFILE = 108;
const REQUEST_SET_UICC_SUBSCRIPTION = 109;
const REQUEST_SET_DATA_SUBSCRIPTION = 110;
const REQUEST_GET_UICC_SUBSCRIPTION = 111;
const REQUEST_GET_DATA_SUBSCRIPTION = 112;
const REQUEST_SET_SUBSCRIPTION_MODE = 113;
const REQUEST_SET_TRANSMIT_POWER = 114;
const REQUEST_SETUP_QOS = 115;
const REQUEST_RELEASE_QOS = 116;
const REQUEST_GET_QOS_STATUS = 117;
const REQUEST_MODIFY_QOS = 118;
const REQUEST_SUSPEND_QOS = 119;
const REQUEST_RESUME_QOS = 120;
const RESPONSE_TYPE_SOLICITED = 0;
const RESPONSE_TYPE_UNSOLICITED = 1;
@ -148,7 +170,7 @@ const RESPONSE_TYPE_UNSOLICITED = 1;
const UNSOLICITED_RESPONSE_BASE = 1000;
const UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED = 1000;
const UNSOLICITED_RESPONSE_CALL_STATE_CHANGED = 1001;
const UNSOLICITED_RESPONSE_NETWORK_STATE_CHANGED = 1002;
const UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002;
const UNSOLICITED_RESPONSE_NEW_SMS = 1003;
const UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
const UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM = 1005;
@ -177,6 +199,20 @@ const UNSOLICITED_CDMA_INFO_REC = 1027;
const UNSOLICITED_OEM_HOOK_RAW = 1028;
const UNSOLICITED_RINGBACK_TONE = 1029;
const UNSOLICITED_RESEND_INCALL_MUTE = 1030;
const UNSOLICITED_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1031;
const UNSOLICITED_CDMA_PRL_CHANGED = 1032;
const UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE = 1033;
const UNSOLICITED_RIL_CONNECTED = 1034;
// Akami/Maguro specific parcels.
const UNSOLICITED_VOICE_RADIO_TECH_CHANGED = 1034;
const UNSOLICITED_RESPONSE_IMS_NETWORK_STATE_CHANGED = 1035;
const UNSOLICITED_RESPONSE_TETHERED_MODE_STATE_CHANGED = 1036;
const UNSOLICITED_RESPONSE_DATA_NETWORK_STATE_CHANGED = 1037;
const UNSOLICITED_ON_SS = 1038;
const UNSOLICITED_STK_CC_ALPHA_NOTIFY = 1039;
const UNSOLICITED_UICC_SUBSCRIPTION_STATUS_CHANGED = 1040;
const UNSOLICITED_QOS_STATE_CHANGED_IND = 1041;
const ERROR_SUCCESS = 0;
const ERROR_RADIO_NOT_AVAILABLE = 1;
@ -194,9 +230,22 @@ const ERROR_SUBSCRIPTION_NOT_AVAILABLE = 12;
const ERROR_MODE_NOT_SUPPORTED = 13;
const ERROR_FDN_CHECK_FAILURE = 14;
const ERROR_ILLEGAL_SIM_OR_ME = 15;
const ERROR_DIAL_MODIFIED_TO_USSD = 17;
const ERROR_DIAL_MODIFIED_TO_SS = 18;
const ERROR_DIAL_MODIFIED_TO_DIAL = 19;
const ERROR_USSD_MODIFIED_TO_DIAL = 20;
const ERROR_USSD_MODIFIED_TO_SS = 21;
const ERROR_USSD_MODIFIED_TO_USSD = 22;
const ERROR_SS_MODIFIED_TO_DIAL = 23;
const ERROR_SS_MODIFIED_TO_USSD = 24;
const ERROR_SS_MODIFIED_TO_SS = 25;
const ERROR_SUBSCRIPTION_NOT_SUPPORTED = 26;
const RADIO_STATE_OFF = 0;
const RADIO_STATE_UNAVAILABLE = 1;
const RADIO_STATE_ON = 2;
// RIL v5 legacy constants:
const RADIO_STATE_SIM_NOT_READY = 2;
const RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3;
const RADIO_STATE_SIM_READY = 4;
@ -210,17 +259,74 @@ const CARD_STATE_ABSENT = 0;
const CARD_STATE_PRESENT = 1;
const CARD_STATE_ERROR = 2;
const CARD_APP_STATE_UNKNOWN = 0;
const CARD_APP_STATE_DETECTED = 1;
const CARD_APP_STATE_PIN = 2; // If PIN1 or UPin is required.
const CARD_APP_STATE_PUK = 3; // If PUK1 or Puk for UPin is required.
const CARD_APP_STATE_SUBSCRIPTION_PERSO = 4; // perso_substate should be looked
// at when app_state is assigned
// to this value.
const CARD_APP_STATE_READY = 5;
const CARD_PERSOSUBSTATE_UNKNOWN = 0;
const CARD_PERSOSUBSTATE_IN_PROGRESS = 1;
const CARD_PERSOSUBSTATE_READY = 2;
const CARD_PERSOSUBSTATE_SIM_NETWORK = 3;
const CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET = 4;
const CARD_PERSOSUBSTATE_SIM_CORPORATE = 5;
const CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER = 6;
const CARD_PERSOSUBSTATE_SIM_SIM = 7;
const CARD_PERSOSUBSTATE_SIM_NETWORK_PUK = 8;
const CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK = 9;
const CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK = 10;
const CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK = 11;
const CARD_PERSOSUBSTATE_SIM_SIM_PUK = 12;
const CARD_PERSOSUBSTATE_RUIM_NETWORK1 = 13;
const CARD_PERSOSUBSTATE_RUIM_NETWORK2 = 14;
const CARD_PERSOSUBSTATE_RUIM_HRPD = 15;
const CARD_PERSOSUBSTATE_RUIM_CORPORATE = 16;
const CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER = 17;
const CARD_PERSOSUBSTATE_RUIM_RUIM = 18;
const CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK = 19;
const CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK = 20;
const CARD_PERSOSUBSTATE_RUIM_HRPD_PUK = 21;
const CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK = 22;
const CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK = 23;
const CARD_PERSOSUBSTATE_RUIM_RUIM_PUK = 24;
const CARD_APPSTATE_ILLEGAL = -1;
const CARD_APPSTATE_UNKNOWN = 0;
const CARD_APPSTATE_DETECTED = 1;
const CARD_APPSTATE_PIN = 2; // If PIN1 or UPin is required.
const CARD_APPSTATE_PUK = 3; // If PUK1 or Puk for UPin is required.
const CARD_APPSTATE_SUBSCRIPTION_PERSO = 4; // perso_substate should be looked
// at when app_state is assigned
// to this value.
const CARD_APPSTATE_READY = 5;
const CARD_PINSTATE_UNKNOWN = 0;
const CARD_PINSTATE_ENABLED_NOT_VERIFIED = 1;
const CARD_PINSTATE_ENABLED_VERIFIED = 2;
const CARD_PINSTATE_DISABLED = 3;
const CARD_PINSTATE_ENABLED_BLOCKED = 4;
const CARD_PINSTATE_ENABLED_PERM_BLOCKED = 5;
const CARD_APPTYPE_UNKNOWN = 0;
const CARD_APPTYPE_SIM = 1;
const CARD_APPTYPE_USIM = 2;
const CARD_APPTYPE_RUIM = 3;
const CARD_APPTYPE_CSIM = 4;
const CARD_APPTYPE_ISIM = 5;
const CARD_MAX_APPS = 8;
const NETWORK_SELECTION_MODE_AUTOMATIC = 0;
const NETWORK_SELECTION_MODE_MANUAL = 1;
const PREFERRED_NETWORK_TYPE_GSM_WCDMA = 0;
const PREFERRED_NETWORK_TYPE_GSM_ONLY = 1;
const PREFERRED_NETWORK_TYPE_WCDMA = 2;
const PREFERRED_NETWORK_TYPE_GSM_WCDMA_AUTO = 3;
const PREFERRED_NETWORK_TYPE_CDMA_EVDO_AUTO = 4;
const PREFERRED_NETWORK_TYPE_CDMA_ONLY = 5;
const PREFERRED_NETWORK_TYPE_EVDO_ONLY = 6;
const PREFERRED_NETWORK_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7;
const PREFERRED_NETWORK_TYPE_LTE_CDMA_EVDO = 8;
const PREFERRED_NETWORK_TYPE_LTE_GSM_WCDMA = 9;
const PREFERRED_NETWORK_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10;
const PREFERRED_NETWORK_TYPE_LTE_ONLY = 11;
// Network registration states. See TS 27.007 7.2
const NETWORK_CREG_STATE_NOT_SEARCHING = 0;
const NETWORK_CREG_STATE_REGISTERED_HOME = 1;
@ -242,6 +348,9 @@ const NETWORK_CREG_TECH_HSDPA = 9;
const NETWORK_CREG_TECH_HSUPA = 10;
const NETWORK_CREG_TECH_HSPA = 11;
const NETWORK_CREG_TECH_EVDOB = 12;
const NETWORK_CREG_TECH_EHRPD = 13;
const NETWORK_CREG_TECH_LTE = 14;
const NETWORK_CREG_TECH_HSPAP = 15;
const CALL_STATE_ACTIVE = 0;
const CALL_STATE_HOLDING = 1;
@ -1094,6 +1203,9 @@ const PDU_NL_SINGLE_SHIFT_TABLES = [
+ " "
];
const RADIOTECH_FAMILY_3GPP = 1; // GSM, WCDMA, LTE
const RADIOTECH_FAMILY_3GPP2 = 2; // CDMA, EVDO
const DATACALL_RADIOTECHNOLOGY_CDMA = 0;
const DATACALL_RADIOTECHNOLOGY_GSM = 1;
@ -1114,6 +1226,30 @@ const DATACALL_INACTIVE = 0;
const DATACALL_ACTIVE_DOWN = 1;
const DATACALL_ACTIVE_UP = 2;
const DATACALL_FAIL_NONE = 0;
const DATACALL_FAIL_OPERATOR_BARRED = 0x08;
const DATACALL_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
const DATACALL_FAIL_MISSING_UKNOWN_APN = 0x1B;
const DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
const DATACALL_FAIL_USER_AUTHENTICATION = 0x1D;
const DATACALL_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
const DATACALL_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
const DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
const DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
const DATACALL_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
const DATACALL_FAIL_NSAPI_IN_USE = 0x23;
const DATACALL_FAIL_ONLY_IPV4_ALLOWED = 0x32;
const DATACALL_FAIL_ONLY_IPV6_ALLOWED = 0x33;
const DATACALL_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34;
const DATACALL_FAIL_PROTOCOL_ERRORS = 0x6F;
const DATACALL_FAIL_VOICE_REGISTRATION_FAIL = -1;
const DATACALL_FAIL_DATA_REGISTRATION_FAIL = -2;
const DATACALL_FAIL_SIGNAL_LOST = -3;
const DATACALL_FAIL_PREF_RADIO_TECH_CHANGED = -4;
const DATACALL_FAIL_RADIO_POWER_OFF = -5;
const DATACALL_FAIL_TETHERED_CALL_ACTIVE = -6;
const DATACALL_FAIL_ERROR_UNSPECIFIED = 0xffff;
// Keep consistent with nsINetworkManager.NETWORK_STATE_*.
const GECKO_NETWORK_STATE_UNKNOWN = -1;
const GECKO_NETWORK_STATE_CONNECTING = 0;
@ -1123,7 +1259,7 @@ const GECKO_NETWORK_STATE_DISCONNECTING = 3;
const GECKO_NETWORK_STATE_DISCONNECTED = 4;
// Other Gecko-specific constants
const GECKO_RADIOSTATE_UNAVAILABLE = "unavailable";
const GECKO_RADIOSTATE_UNAVAILABLE = null;
const GECKO_RADIOSTATE_OFF = "off";
const GECKO_RADIOSTATE_READY = "ready";
@ -1149,6 +1285,9 @@ const GECKO_RADIO_TECH = [
"hsupa",
"hspa",
"evdob",
"ehrpd",
"lte",
"hspa+",
];
// Allow this file to be imported via Components.utils.import().

View File

@ -77,6 +77,9 @@ const PARCEL_SIZE_SIZE = UINT32_SIZE;
let RILQUIRKS_CALLSTATE_EXTRA_UINT32 = false;
let RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = false;
// This flag defaults to true since on RIL v6 and later, we get the
// version number via the UNSOLICITED_RIL_CONNECTED parcel.
let RILQUIRKS_V5_LEGACY = true;
/**
* This object contains helpers buffering incoming data & deconstructing it
@ -554,7 +557,7 @@ let RIL = {
/**
* One of the RADIO_STATE_* constants.
*/
radioState: RADIO_STATE_UNAVAILABLE,
radioState: GECKO_RADIOSTATE_UNAVAILABLE,
/**
* ICC status. Keeps a reference of the data response to the
@ -576,8 +579,8 @@ let RIL = {
SMSC: null,
MSISDN: null,
registrationState: {},
gprsRegistrationState: {},
voiceRegistrationState: {},
dataRegistrationState: {},
/**
* List of strings identifying the network operator.
@ -651,6 +654,13 @@ let RIL = {
RILQUIRKS_CALLSTATE_EXTRA_UINT32 = true;
RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = true;
}
if (model_id == "I9023" || model_id == "I9020") {
if (DEBUG) {
debug("Detected I9020/I9023, enabling " +
"RILQUIRKS_DATACALLSTATE_DOWN_IS_UP");
}
RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = true;
}
this.rilQuirksInitialized = true;
},
@ -820,12 +830,12 @@ let RIL = {
Buf.sendParcel();
},
getRegistrationState: function getRegistrationState() {
Buf.simpleRequest(REQUEST_REGISTRATION_STATE);
getVoiceRegistrationState: function getVoiceRegistrationState() {
Buf.simpleRequest(REQUEST_VOICE_REGISTRATION_STATE);
},
getGPRSRegistrationState: function getGPRSRegistrationState() {
Buf.simpleRequest(REQUEST_GPRS_REGISTRATION_STATE);
getDataRegistrationState: function getDataRegistrationState() {
Buf.simpleRequest(REQUEST_DATA_REGISTRATION_STATE);
},
getOperator: function getOperator() {
@ -836,13 +846,29 @@ let RIL = {
Buf.simpleRequest(REQUEST_QUERY_NETWORK_SELECTION_MODE);
},
setNetworkSelectionAutomatic: function setNetworkSelectionAutomatic() {
Buf.simpleRequest(REQUEST_SET_NETWORK_SELECTION_AUTOMATIC);
},
/**
* Set the preferred network type.
*
* @param network_type
* The network type. One of the PREFERRED_NETWORK_TYPE_* constants.
*/
setPreferredNetworkType: function setPreferredNetworkType(network_type) {
Buf.newParcel(REQUEST_SET_PREFERRED_NETWORK_TYPE);
Buf.writeUint32(network_type);
Buf.sendParcel();
},
/**
* Request various states about the network.
*/
requestNetworkInfo: function requestNetworkInfo() {
if (DEBUG) debug("Requesting phone state");
this.getRegistrationState();
this.getGPRSRegistrationState(); //TODO only GSM
this.getVoiceRegistrationState();
this.getDataRegistrationState(); //TODO only GSM
this.getOperator();
this.getNetworkSelectionMode();
},
@ -1168,68 +1194,50 @@ let RIL = {
return;
}
if ((this.radioState == RADIO_STATE_OFF) ||
(this.radioState == RADIO_STATE_UNAVAILABLE) ||
(this.radioState == RADIO_STATE_SIM_NOT_READY) ||
(this.radioState == RADIO_STATE_RUIM_NOT_READY) ||
(this.radioState == RADIO_STATE_NV_NOT_READY) ||
(this.radioState == RADIO_STATE_NV_READY)) {
if (DEBUG) debug("ICC not ready");
if (this.cardState == GECKO_CARDSTATE_NOT_READY) {
let app = iccStatus.apps[iccStatus.gsmUmtsSubscriptionAppIndex];
if (!app) {
if (DEBUG) {
debug("Subscription application is not present in iccStatus.");
}
if (this.cardState == GECKO_CARDSTATE_ABSENT) {
return;
}
this.cardState = GECKO_CARDSTATE_NOT_READY;
this.cardState = GECKO_CARDSTATE_ABSENT;
this.operator = null;
this.sendDOMMessage({type: "cardstatechange",
cardState: this.cardState});
return;
}
if ((this.radioState == RADIO_STATE_SIM_LOCKED_OR_ABSENT) ||
(this.radioState == RADIO_STATE_SIM_READY) ||
(this.radioState == RADIO_STATE_RUIM_LOCKED_OR_ABSENT) ||
(this.radioState == RADIO_STATE_RUIM_READY)) {
let app = iccStatus.apps[iccStatus.gsmUmtsSubscriptionAppIndex];
if (!app) {
if (DEBUG) {
debug("Subscription application is not present in iccStatus.");
}
if (this.cardState == GECKO_CARDSTATE_ABSENT) {
return;
}
this.cardState = GECKO_CARDSTATE_ABSENT;
this.operator = null;
this.sendDOMMessage({type: "cardstatechange",
cardState: this.cardState});
return;
}
let newCardState;
switch (app.app_state) {
case CARD_APP_STATE_PIN:
newCardState = GECKO_CARDSTATE_PIN_REQUIRED;
break;
case CARD_APP_STATE_PUK:
newCardState = GECKO_CARDSTATE_PUK_REQUIRED;
break;
case CARD_APP_STATE_SUBSCRIPTION_PERSO:
newCardState = GECKO_CARDSTATE_NETWORK_LOCKED;
break;
case CARD_APP_STATE_READY:
newCardState = GECKO_CARDSTATE_READY;
break;
case CARD_APP_STATE_UNKNOWN:
case CARD_APP_STATE_DETECTED:
default:
newCardState = GECKO_CARDSTATE_NOT_READY;
}
if (this.cardState == newCardState) {
return;
}
this.cardState = newCardState;
this.sendDOMMessage({type: "cardstatechange",
cardState: this.cardState});
let newCardState;
switch (app.app_state) {
case CARD_APPSTATE_PIN:
newCardState = GECKO_CARDSTATE_PIN_REQUIRED;
break;
case CARD_APPSTATE_PUK:
newCardState = GECKO_CARDSTATE_PUK_REQUIRED;
break;
case CARD_APPSTATE_SUBSCRIPTION_PERSO:
newCardState = GECKO_CARDSTATE_NETWORK_LOCKED;
break;
case CARD_APPSTATE_READY:
this.requestNetworkInfo();
this.getSignalStrength();
this.getMSISDN();
newCardState = GECKO_CARDSTATE_READY;
break;
case CARD_APPSTATE_UNKNOWN:
case CARD_APPSTATE_DETECTED:
default:
newCardState = GECKO_CARDSTATE_NOT_READY;
}
if (this.cardState == newCardState) {
return;
}
this.cardState = newCardState;
this.sendDOMMessage({type: "cardstatechange",
cardState: this.cardState});
},
/**
@ -1274,14 +1282,18 @@ let RIL = {
}
},
_processRegistrationState: function _processRegistrationState(state) {
let rs = this.registrationState;
_processVoiceRegistrationState: function _processVoiceRegistrationState(state) {
let rs = this.voiceRegistrationState;
let stateChanged = false;
let regState = RIL.parseInt(state[0], NETWORK_CREG_STATE_UNKNOWN);
if (rs.regState != regState) {
rs.regState = regState;
stateChanged = true;
if (regState == NETWORK_CREG_STATE_REGISTERED_HOME ||
regState == NETWORK_CREG_STATE_REGISTERED_ROAMING) {
RIL.getSMSCAddress();
}
}
let radioTech = RIL.parseInt(state[3], NETWORK_CREG_TECH_UNKNOWN);
@ -1310,13 +1322,13 @@ let RIL = {
}
if (stateChanged) {
this.sendDOMMessage({type: "registrationstatechange",
registrationState: rs});
this.sendDOMMessage({type: "voiceregistrationstatechange",
voiceRegistrationState: rs});
}
},
_processGPRSRegistrationState: function _processGPRSRegistrationState(state) {
let rs = this.gprsRegistrationState;
_processDataRegistrationState: function _processDataRegistrationState(state) {
let rs = this.dataRegistrationState;
let stateChanged = false;
let regState = RIL.parseInt(state[0], NETWORK_CREG_STATE_UNKNOWN);
@ -1332,8 +1344,8 @@ let RIL = {
}
if (stateChanged) {
this.sendDOMMessage({type: "gprsregistrationstatechange",
gprsRegistrationState: rs});
this.sendDOMMessage({type: "dataregistrationstatechange",
dataRegistrationState: rs});
}
},
@ -1386,6 +1398,72 @@ let RIL = {
this.muted = Object.getOwnPropertyNames(this.currentCalls).length == 0;
},
_handleChangedCallState: function _handleChangedCallState(changedCall) {
let message = {type: "callStateChange",
call: {callIndex: changedCall.callIndex,
state: changedCall.state,
number: changedCall.number,
name: changedCall.name}};
this.sendDOMMessage(message);
},
_handleDisconnectedCall: function _handleDisconnectedCall(disconnectedCall) {
let message = {type: "callDisconnected",
call: {callIndex: disconnectedCall.callIndex}};
this.sendDOMMessage(message);
},
_processDataCallList: function _processDataCallList(datacalls) {
for each (let currentDataCall in this.currentDataCalls) {
let updatedDataCall;
if (datacalls) {
updatedDataCall = datacalls[currentDataCall.cid];
delete datacalls[currentDataCall.cid];
}
if (!updatedDataCall) {
delete this.currentDataCalls[currentDataCall.callIndex];
currentDataCall.state = GECKO_NETWORK_STATE_DISCONNECTED;
this.sendDOMMessage({type: "datacallstatechange",
datacall: currentDataCall});
continue;
}
this._setDataCallGeckoState(updatedDataCall);
if (updatedDataCall.state != currentDataCall.state) {
currentDataCall.status = updatedDataCall.status;
currentDataCall.active = updatedDataCall.active;
currentDataCall.state = updatedDataCall.state;
this.sendDOMMessage({type: "datacallstatechange",
datacall: currentDataCall});
}
}
for each (let newDataCall in datacalls) {
this.currentDataCalls[newDataCall.cid] = newDataCall;
this._setDataCallGeckoState(newDataCall);
this.sendDOMMessage({type: "datacallstatechange",
datacall: newDataCall});
}
},
_setDataCallGeckoState: function _setDataCallGeckoState(datacall) {
switch (datacall.active) {
case DATACALL_INACTIVE:
datacall.state = GECKO_NETWORK_STATE_DISCONNECTED;
break;
case DATACALL_ACTIVE_DOWN:
datacall.state = GECKO_NETWORK_STATE_SUSPENDED;
if (RILQUIRKS_DATACALLSTATE_DOWN_IS_UP) {
datacall.state = GECKO_NETWORK_STATE_CONNECTED;
}
break;
case DATACALL_ACTIVE_UP:
datacall.state = GECKO_NETWORK_STATE_CONNECTED;
break;
}
},
/**
* Helper for processing received multipart SMS.
*
@ -1439,63 +1517,6 @@ let RIL = {
return options;
},
_handleChangedCallState: function _handleChangedCallState(changedCall) {
let message = {type: "callStateChange",
call: {callIndex: changedCall.callIndex,
state: changedCall.state,
number: changedCall.number,
name: changedCall.name}};
this.sendDOMMessage(message);
},
_handleDisconnectedCall: function _handleDisconnectedCall(disconnectedCall) {
let message = {type: "callDisconnected",
call: {callIndex: disconnectedCall.callIndex}};
this.sendDOMMessage(message);
},
_processDataCallList: function _processDataCallList(datacalls) {
for each (let currentDataCall in this.currentDataCalls) {
let newDataCall;
if (datacalls) {
newDataCall = datacalls[currentDataCall.cid];
delete datacalls[currentDataCall.cid];
}
if (newDataCall) {
switch (newDataCall.active) {
case DATACALL_INACTIVE:
newDataCall.state = GECKO_NETWORK_STATE_DISCONNECTED;
break;
case DATACALL_ACTIVE_DOWN:
newDataCall.state = GECKO_NETWORK_STATE_SUSPENDED;
if (RILQUIRKS_DATACALLSTATE_DOWN_IS_UP) {
newDataCall.state = GECKO_NETWORK_STATE_CONNECTED;
}
break;
case DATACALL_ACTIVE_UP:
newDataCall.state = GECKO_NETWORK_STATE_CONNECTED;
break;
}
if (newDataCall.state != currentDataCall.state) {
currentDataCall.active = newDataCall.active;
currentDataCall.state = newDataCall.state;
this.sendDOMMessage({type: "datacallstatechange",
datacall: currentDataCall});
}
} else {
delete this.currentDataCalls[currentDataCall.callIndex];
currentDataCall.state = GECKO_NETWORK_STATE_DISCONNECTED;
this.sendDOMMessage({type: "datacallstatechange",
datacall: currentDataCall});
}
}
for each (let datacall in datacalls) {
if (DEBUG) debug("Unexpected data call: " + JSON.stringify(datacall));
}
},
/**
* Handle incoming messages from the main UI thread.
*
@ -1569,24 +1590,26 @@ let RIL = {
};
RIL[REQUEST_GET_SIM_STATUS] = function REQUEST_GET_SIM_STATUS() {
let iccStatus = {
cardState: Buf.readUint32(), // CARD_STATE_*
universalPINState: Buf.readUint32(), // PINSTATE_*
gsmUmtsSubscriptionAppIndex: Buf.readUint32(),
setCdmaSubscriptionAppIndex: Buf.readUint32(),
apps: []
};
let iccStatus = {};
iccStatus.cardState = Buf.readUint32(); // CARD_STATE_*
iccStatus.universalPINState = Buf.readUint32(); // CARD_PINSTATE_*
iccStatus.gsmUmtsSubscriptionAppIndex = Buf.readUint32();
iccStatus.cdmaSubscriptionAppIndex = Buf.readUint32();
if (!RILQUIRKS_V5_LEGACY) {
iccStatus.imsSubscriptionAppIndex = Buf.readUint32();
}
let apps_length = Buf.readUint32();
if (apps_length > CARD_MAX_APPS) {
apps_length = CARD_MAX_APPS;
}
iccStatus.apps = [];
for (let i = 0 ; i < apps_length ; i++) {
iccStatus.apps.push({
app_type: Buf.readUint32(), // APPTYPE_*
app_state: Buf.readUint32(), // CARD_APP_STATE_*
perso_substate: Buf.readUint32(), // PERSOSUBSTATE_*
app_type: Buf.readUint32(), // CARD_APPTYPE_*
app_state: Buf.readUint32(), // CARD_APPSTATE_*
perso_substate: Buf.readUint32(), // CARD_PERSOSUBSTATE_*
aid: Buf.readString(),
app_label: Buf.readString(),
pin1_replaced: Buf.readUint32(),
@ -1673,43 +1696,65 @@ RIL[REQUEST_CONFERENCE] = null;
RIL[REQUEST_UDUB] = null;
RIL[REQUEST_LAST_CALL_FAIL_CAUSE] = null;
RIL[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH() {
let signalStrength = Buf.readUint32();
let obj = {};
// GSM
// Valid values are (0-31, 99) as defined in TS 27.007 8.5.
obj.gsmSignalStrength = Buf.readUint32();
// The SGS2 seems to compute the number of bars for us and expose those
// instead of the actual signal strength.
let bars = signalStrength >> 8;
signalStrength = signalStrength & 0xff;
let strength = {
obj.bars = obj.gsmSignalStrength >> 8; //TODO remove this, see bug 729173
obj.gsmSignalStrength = obj.gsmSignalStrength & 0xff;
// GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5.
obj.gsmBitErrorRate = Buf.readUint32();
// CDMA
// The CDMA RSSI value.
obj.cdmaDBM = Buf.readUint32();
// The CDMA EC/IO.
obj.cdmaECIO = Buf.readUint32();
// The EVDO RSSI value.
// EVDO
obj.evdoDBM = Buf.readUint32();
// The EVDO EC/IO.
obj.evdoECIO = Buf.readUint32();
// Signal-to-noise ratio. Valid values are 0 to 8.
obj.evdoSNR = Buf.readUint32();
// LTE
if (!RILQUIRKS_V5_LEGACY) {
// Valid values are (0-31, 99) as defined in TS 27.007 8.5.
gsmSignalStrength: signalStrength,
// Non-standard extension by the SGS2.
bars: bars,
// GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5.
gsmBitErrorRate: Buf.readUint32(),
// The CDMA RSSI value.
cdmaDBM: Buf.readUint32(),
// The CDMA EC/IO.
cdmaECIO: Buf.readUint32(),
// The EVDO RSSI value.
evdoDBM: Buf.readUint32(),
// The EVDO EC/IO.
evdoECIO: Buf.readUint32(),
// Valid values are 0-8. 8 is the highest signal to noise ratio
evdoSNR: Buf.readUint32()
};
if (DEBUG) debug("Signal strength " + JSON.stringify(strength));
obj.lteSignalStrength = Buf.readUint32();
// Reference signal receive power in dBm, multiplied by -1.
// Valid values are 44 to 140.
obj.lteRSRP = Buf.readUint32();
// Reference signal receive quality in dB, multiplied by -1.
// Valid values are 3 to 20.
obj.lteRSRQ = Buf.readUint32();
// Signal-to-noise ratio for the reference signal.
// Valid values are -200 (20.0 dB) to +300 (30 dB).
obj.lteRSSNR = Buf.readUint32();
// Channel Quality Indicator, valid values are 0 to 15.
obj.lteCQI = Buf.readUint32();
}
if (DEBUG) debug("Signal strength " + JSON.stringify(obj));
this.sendDOMMessage({type: "signalstrengthchange",
signalStrength: strength});
signalStrength: obj});
};
RIL[REQUEST_REGISTRATION_STATE] = function REQUEST_REGISTRATION_STATE(length) {
RIL[REQUEST_VOICE_REGISTRATION_STATE] = function REQUEST_VOICE_REGISTRATION_STATE(length) {
let state = Buf.readStringList();
this._processRegistrationState(state);
debug("voice registration state: " + state);
this._processVoiceRegistrationState(state);
};
RIL[REQUEST_GPRS_REGISTRATION_STATE] = function REQUEST_GPRS_REGISTRATION_STATE(length) {
RIL[REQUEST_DATA_REGISTRATION_STATE] = function REQUEST_DATA_REGISTRATION_STATE(length) {
let state = Buf.readStringList();
this._processGPRSRegistrationState(state);
this._processDataRegistrationState(state);
};
RIL[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length) {
let operator = Buf.readStringList();
if (DEBUG) debug("Operator data: " + operator);
if (operator.length < 3) {
if (DEBUG) debug("Expected at least 3 strings for operator.");
}
@ -1748,7 +1793,11 @@ RIL[REQUEST_SEND_SMS] = function REQUEST_SEND_SMS(length, options) {
this.sendDOMMessage(options);
};
RIL[REQUEST_SEND_SMS_EXPECT_MORE] = null;
RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options) {
RIL.readSetupDataCall_v5 = function readSetupDataCall_v5(options) {
if (!options) {
options = {};
}
let [cid, ifname, ipaddr, dns, gw] = Buf.readStringList();
options.cid = cid;
options.ifname = ifname;
@ -1757,13 +1806,21 @@ RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options)
options.gw = gw;
options.active = DATACALL_ACTIVE_UNKNOWN;
options.state = GECKO_NETWORK_STATE_CONNECTING;
this.currentDataCalls[options.cid] = options;
this.sendDOMMessage({type: "datacallstatechange",
datacall: options});
return options;
};
// Let's get the list of data calls to ensure we know whether it's active
// or not.
this.getDataCallList();
RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options) {
if (RILQUIRKS_V5_LEGACY) {
this.readSetupDataCall_v5(options);
this.currentDataCalls[options.cid] = options;
this.sendDOMMessage({type: "datacallstatechange",
datacall: options});
// Let's get the list of data calls to ensure we know whether it's active
// or not.
this.getDataCallList();
return;
}
this[REQUEST_DATA_CALL_LIST](length, options);
};
RIL[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) {
switch (options.fileid) {
@ -1809,33 +1866,70 @@ RIL[REQUEST_DTMF_START] = null;
RIL[REQUEST_DTMF_STOP] = null;
RIL[REQUEST_BASEBAND_VERSION] = function REQUEST_BASEBAND_VERSION() {
this.basebandVersion = Buf.readString();
if (DEBUG) debug("Baseband version: " + this.basebandVersion);
};
RIL[REQUEST_SEPARATE_CONNECTION] = null;
RIL[REQUEST_SET_MUTE] = null;
RIL[REQUEST_GET_MUTE] = null;
RIL[REQUEST_QUERY_CLIP] = null;
RIL[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
RIL.readDataCall_v5 = function readDataCall_v5() {
return {
cid: Buf.readUint32().toString(),
active: Buf.readUint32(), // DATACALL_ACTIVE_*
type: Buf.readString(),
apn: Buf.readString(),
address: Buf.readString()
};
};
RIL.readDataCall_v6 = function readDataCall_v6(obj) {
if (!obj) {
obj = {};
}
obj.status = Buf.readUint32(); // DATACALL_FAIL_*
obj.suggestedRetryTime = Buf.readUint32();
obj.cid = Buf.readUint32().toString();
obj.active = Buf.readUint32(); // DATACALL_ACTIVE_*
obj.type = Buf.readString();
obj.ifname = Buf.readString();
obj.ipaddr = Buf.readString();
obj.dns = Buf.readString();
obj.gw = Buf.readString();
if (obj.dns) {
obj.dns = obj.dns.split(" ");
}
//TODO for now we only support one address and gateway
if (obj.ipaddr) {
obj.ipaddr = obj.ipaddr.split(" ")[0];
}
if (obj.gw) {
obj.gw = obj.gw.split(" ")[0];
}
return obj;
};
RIL[REQUEST_DATA_CALL_LIST] = function REQUEST_DATA_CALL_LIST(length) {
this.initRILQuirks();
let num = 0;
if (length) {
num = Buf.readUint32();
}
if (!num) {
if (!length) {
this._processDataCallList(null);
return;
}
let version = 0;
if (!RILQUIRKS_V5_LEGACY) {
version = Buf.readUint32();
}
let num = num = Buf.readUint32();
let datacalls = {};
for (let i = 0; i < num; i++) {
let datacall = {
cid: Buf.readUint32().toString(),
active: Buf.readUint32(),
type: Buf.readString(),
apn: Buf.readString(),
address: Buf.readString()
};
let datacall;
if (version < 6) {
datacall = this.readDataCall_v5();
} else {
datacall = this.readDataCall_v6();
}
datacalls[datacall.cid] = datacall;
}
@ -1860,7 +1954,7 @@ RIL[REQUEST_SET_PREFERRED_NETWORK_TYPE] = null;
RIL[REQUEST_GET_PREFERRED_NETWORK_TYPE] = null;
RIL[REQUEST_GET_NEIGHBORING_CELL_IDS] = null;
RIL[REQUEST_SET_LOCATION_UPDATES] = null;
RIL[REQUEST_CDMA_SET_SUBSCRIPTION] = null;
RIL[REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE] = null;
RIL[REQUEST_CDMA_SET_ROAMING_PREFERENCE] = null;
RIL[REQUEST_CDMA_QUERY_ROAMING_PREFERENCE] = null;
RIL[REQUEST_SET_TTY_MODE] = null;
@ -1899,97 +1993,71 @@ RIL[REQUEST_SET_SMSC_ADDRESS] = null;
RIL[REQUEST_REPORT_SMS_MEMORY_STATUS] = null;
RIL[REQUEST_REPORT_STK_SERVICE_IS_RUNNING] = null;
RIL[UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED] = function UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED() {
let newState = Buf.readUint32();
let radioState = Buf.readUint32();
let newState;
if (radioState == RADIO_STATE_UNAVAILABLE) {
newState = GECKO_RADIOSTATE_UNAVAILABLE;
} else if (radioState == RADIO_STATE_OFF) {
newState = GECKO_RADIOSTATE_OFF;
} else {
newState = GECKO_RADIOSTATE_READY;
}
if (DEBUG) {
debug("Radio state changed from " + this.radioState + " to " + newState);
debug("Radio state changed from '" + this.radioState +
"' to '" + newState + "'");
}
if (this.radioState == newState) {
// No change in state, return.
return;
}
let gsm = newState == RADIO_STATE_SIM_NOT_READY ||
newState == RADIO_STATE_SIM_LOCKED_OR_ABSENT ||
newState == RADIO_STATE_SIM_READY;
let cdma = newState == RADIO_STATE_RUIM_NOT_READY ||
newState == RADIO_STATE_RUIM_READY ||
newState == RADIO_STATE_RUIM_LOCKED_OR_ABSENT ||
newState == RADIO_STATE_NV_NOT_READY ||
newState == RADIO_STATE_NV_READY;
// TODO hardcoded for now (see bug 726098)
let cdma = false;
// Figure out state transitions and send out more RIL requests as necessary
// as well as events to the main thread.
if (this.radioState == RADIO_STATE_UNAVAILABLE &&
newState != RADIO_STATE_UNAVAILABLE) {
if (this.radioState == GECKO_RADIOSTATE_UNAVAILABLE &&
newState != GECKO_RADIOSTATE_UNAVAILABLE) {
// The radio became available, let's get its info.
if (gsm) {
if (cdma) {
this.getDeviceIdentity();
} else {
this.getIMEI();
this.getIMEISV();
}
if (cdma) {
this.getDeviceIdentity();
}
this.getBasebandVersion();
this.setScreenState(true);
this.sendDOMMessage({
type: "radiostatechange",
radioState: (newState == RADIO_STATE_OFF) ?
GECKO_RADIOSTATE_OFF : GECKO_RADIOSTATE_READY
});
//XXX TODO For now, just turn the radio on if it's off. for the real
// deal we probably want to do the opposite: start with a known state
// when we boot up and let the UI layer control the radio power.
if (newState == RADIO_STATE_OFF) {
if (newState == GECKO_RADIOSTATE_OFF) {
this.setRadioPower(true);
}
}
if (newState == RADIO_STATE_UNAVAILABLE) {
// The radio is no longer available, we need to deal with any
// remaining pending requests.
//TODO do that
this.sendDOMMessage({type: "radiostatechange",
radioState: GECKO_RADIOSTATE_UNAVAILABLE});
}
if (newState == RADIO_STATE_SIM_READY ||
newState == RADIO_STATE_RUIM_READY ||
newState == RADIO_STATE_NV_READY) {
// The ICC has become available. Get all the things.
this.getICCStatus();
this.requestNetworkInfo();
this.getSignalStrength();
this.getSMSCAddress();
this.getMSISDN();
this.sendDOMMessage({type: "cardstatechange",
cardState: GECKO_CARDSTATE_READY});
}
if (newState == RADIO_STATE_SIM_LOCKED_OR_ABSENT ||
newState == RADIO_STATE_RUIM_LOCKED_OR_ABSENT) {
this.getICCStatus();
this.sendDOMMessage({type: "cardstatechange",
cardState: GECKO_CARDSTATE_UNAVAILABLE});
}
let wasOn = this.radioState != RADIO_STATE_OFF &&
this.radioState != RADIO_STATE_UNAVAILABLE;
let isOn = newState != RADIO_STATE_OFF &&
newState != RADIO_STATE_UNAVAILABLE;
if (!wasOn && isOn) {
//TODO
}
if (wasOn && !isOn) {
//TODO
}
this.radioState = newState;
this.sendDOMMessage({
type: "radiostatechange",
radioState: newState
});
// If the radio is up and on, so let's query the card state.
// On older RILs only if the card is actually ready, though.
if (radioState == RADIO_STATE_UNAVAILABLE ||
radioState == RADIO_STATE_OFF) {
return;
}
if (RILQUIRKS_V5_LEGACY &&
(radioState == RADIO_STATE_SIM_NOT_READY ||
radioState == RADIO_STATE_RUIM_NOT_READY ||
radioState == RADIO_STATE_NV_NOT_READY)) {
return;
}
this.getICCStatus();
};
RIL[UNSOLICITED_RESPONSE_CALL_STATE_CHANGED] = function UNSOLICITED_RESPONSE_CALL_STATE_CHANGED() {
this.getCurrentCalls();
};
RIL[UNSOLICITED_RESPONSE_NETWORK_STATE_CHANGED] = function UNSOLICITED_RESPONSE_NETWORK_STATE_CHANGED() {
RIL[UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED] = function UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED() {
if (DEBUG) debug("Network state changed, re-requesting phone state.");
this.requestNetworkInfo();
};
@ -2086,8 +2154,12 @@ RIL[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED()
RIL[UNSOLICITED_SIGNAL_STRENGTH] = function UNSOLICITED_SIGNAL_STRENGTH() {
this[REQUEST_SIGNAL_STRENGTH]();
};
RIL[UNSOLICITED_DATA_CALL_LIST_CHANGED] = function UNSOLICITED_DATA_CALL_LIST_CHANGED(length) {
this.getDataCallList();
RIL[UNSOLICITED_DATA_CALL_LIST_CHANGED] = function UNSOLICITED_DATA_CALL_LIST_CHANGED(length, options) {
if (RILQUIRKS_V5_LEGACY) {
this.getDataCallList();
return;
}
this[REQUEST_GET_DATA_CALL_LIST](length, options);
};
RIL[UNSOLICITED_SUPP_SVC_NOTIFICATION] = null;
RIL[UNSOLICITED_STK_SESSION_END] = null;
@ -2124,6 +2196,14 @@ RIL[UNSOLICITED_CDMA_INFO_REC] = null;
RIL[UNSOLICITED_OEM_HOOK_RAW] = null;
RIL[UNSOLICITED_RINGBACK_TONE] = null;
RIL[UNSOLICITED_RESEND_INCALL_MUTE] = null;
RIL[UNSOLICITED_RIL_CONNECTED] = function UNSOLICITED_RIL_CONNECTED(length, options) {
let version = Buf.readUint32List()[0];
RILQUIRKS_V5_LEGACY = (version < 5);
if (DEBUG) {
debug("Detected RIL version " + version);
debug("RILQUIRKS_V5_LEGACY is " + RILQUIRKS_V5_LEGACY);
}
};
/**

Some files were not shown because too many files have changed in this diff Show More