diff --git a/accessible/atk/AccessibleWrap.cpp b/accessible/atk/AccessibleWrap.cpp index a6e0b70b56ad..0f922cf4c1af 100644 --- a/accessible/atk/AccessibleWrap.cpp +++ b/accessible/atk/AccessibleWrap.cpp @@ -123,23 +123,38 @@ static const GInterfaceInfo atk_if_infos[] = { (GInterfaceFinalizeFunc) nullptr, nullptr} }; -/** - * This MaiAtkObject is a thin wrapper, in the MAI namespace, for AtkObject - */ -struct MaiAtkObject -{ - AtkObject parent; - /* - * The AccessibleWrap whose properties and features are exported - * via this object instance. - */ - uintptr_t accWrap; -}; - // This is or'd with the pointer in MaiAtkObject::accWrap if the wrap-ee is a // proxy. static const uintptr_t IS_PROXY = 1; +static GQuark quark_mai_hyperlink = 0; + +AtkHyperlink* +MaiAtkObject::GetAtkHyperlink() +{ + NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized"); + MaiHyperlink* maiHyperlink = + (MaiHyperlink*)g_object_get_qdata(G_OBJECT(this), quark_mai_hyperlink); + if (!maiHyperlink) { + maiHyperlink = new MaiHyperlink(reinterpret_cast(accWrap)); + g_object_set_qdata(G_OBJECT(this), quark_mai_hyperlink, maiHyperlink); + } + + return maiHyperlink->GetAtkHyperlink(); +} + +void +MaiAtkObject::Shutdown() +{ + accWrap = 0; + MaiHyperlink* maiHyperlink = + (MaiHyperlink*)g_object_get_qdata(G_OBJECT(this), quark_mai_hyperlink); + if (maiHyperlink) { + delete maiHyperlink; + g_object_set_qdata(G_OBJECT(this), quark_mai_hyperlink, nullptr); + } +} + struct MaiAtkObjectClass { AtkObjectClass parent_class; @@ -208,8 +223,6 @@ static const char * GetUniqueMaiAtkTypeName(uint16_t interfacesBits); static gpointer parent_class = nullptr; -static GQuark quark_mai_hyperlink = 0; - GType mai_atk_object_get_type(void) { @@ -250,14 +263,15 @@ AccessibleWrap::~AccessibleWrap() void AccessibleWrap::ShutdownAtkObject() { - if (mAtkObject) { - if (IS_MAI_OBJECT(mAtkObject)) { - MAI_ATK_OBJECT(mAtkObject)->accWrap = 0; - } - SetMaiHyperlink(nullptr); - g_object_unref(mAtkObject); - mAtkObject = nullptr; - } + if (!mAtkObject) + return; + + NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "wrong type of atk object"); + if (IS_MAI_OBJECT(mAtkObject)) + MAI_ATK_OBJECT(mAtkObject)->Shutdown(); + + g_object_unref(mAtkObject); + mAtkObject = nullptr; } void @@ -267,42 +281,6 @@ AccessibleWrap::Shutdown() Accessible::Shutdown(); } -MaiHyperlink* -AccessibleWrap::GetMaiHyperlink(bool aCreate /* = true */) -{ - // make sure mAtkObject is created - GetAtkObject(); - - NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized"); - NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "Invalid AtkObject"); - MaiHyperlink* maiHyperlink = nullptr; - if (quark_mai_hyperlink && IS_MAI_OBJECT(mAtkObject)) { - maiHyperlink = (MaiHyperlink*)g_object_get_qdata(G_OBJECT(mAtkObject), - quark_mai_hyperlink); - if (!maiHyperlink && aCreate) { - maiHyperlink = new MaiHyperlink(this); - SetMaiHyperlink(maiHyperlink); - } - } - return maiHyperlink; -} - -void -AccessibleWrap::SetMaiHyperlink(MaiHyperlink* aMaiHyperlink) -{ - NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized"); - NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "Invalid AtkObject"); - if (quark_mai_hyperlink && IS_MAI_OBJECT(mAtkObject)) { - MaiHyperlink* maiHyperlink = GetMaiHyperlink(false); - if (!maiHyperlink && !aMaiHyperlink) { - return; // Never set and we're shutting down - } - delete maiHyperlink; - g_object_set_qdata(G_OBJECT(mAtkObject), quark_mai_hyperlink, - aMaiHyperlink); - } -} - void AccessibleWrap::GetNativeInterface(void** aOutAccessible) { @@ -1093,7 +1071,7 @@ void a11y::ProxyDestroyed(ProxyAccessible* aProxy) { auto obj = reinterpret_cast(aProxy->GetWrapper() & ~IS_PROXY); - obj->accWrap = 0; + obj->Shutdown(); g_object_unref(obj); aProxy->SetWrapper(0); } diff --git a/accessible/atk/AccessibleWrap.h b/accessible/atk/AccessibleWrap.h index 62a4ba68b55e..3def02ee8ff1 100644 --- a/accessible/atk/AccessibleWrap.h +++ b/accessible/atk/AccessibleWrap.h @@ -63,10 +63,6 @@ public: bool IsValidObject(); - // get/set the MaiHyperlink object for this AccessibleWrap - MaiHyperlink* GetMaiHyperlink(bool aCreate = true); - void SetMaiHyperlink(MaiHyperlink* aMaiHyperlink); - static const char * ReturnString(nsAString &aString) { static nsCString returnedString; returnedString = NS_ConvertUTF16toUTF8(aString); diff --git a/accessible/atk/nsMai.h b/accessible/atk/nsMai.h index 0e61086e28e9..b36bd15958db 100644 --- a/accessible/atk/nsMai.h +++ b/accessible/atk/nsMai.h @@ -51,4 +51,27 @@ IsAtkVersionAtLeast(int aMajor, int aMinor) (aMajor == atkMajorVersion && aMinor <= atkMinorVersion); } +/** + * This MaiAtkObject is a thin wrapper, in the MAI namespace, for AtkObject + */ +struct MaiAtkObject +{ + AtkObject parent; + /* + * The AccessibleWrap whose properties and features are exported + * via this object instance. + */ + uintptr_t accWrap; + + /* + * Get the AtkHyperlink for this atk object. + */ + AtkHyperlink* GetAtkHyperlink(); + + /* + * Shutdown this AtkObject. + */ + void Shutdown(); +}; + #endif /* __NS_MAI_H__ */ diff --git a/accessible/atk/nsMaiHyperlink.cpp b/accessible/atk/nsMaiHyperlink.cpp index ca6c27d62e7a..0b086a0963df 100644 --- a/accessible/atk/nsMaiHyperlink.cpp +++ b/accessible/atk/nsMaiHyperlink.cpp @@ -94,56 +94,28 @@ MaiHyperlink::MaiHyperlink(Accessible* aHyperLink) : mHyperlink(aHyperLink), mMaiAtkHyperlink(nullptr) { -} - -MaiHyperlink::~MaiHyperlink() -{ - if (mMaiAtkHyperlink) { - MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr; - g_object_unref(mMaiAtkHyperlink); - } -} - -AtkHyperlink* -MaiHyperlink::GetAtkHyperlink(void) -{ - NS_ENSURE_TRUE(mHyperlink, nullptr); - - if (mMaiAtkHyperlink) - return mMaiAtkHyperlink; - if (!mHyperlink->IsLink()) - return nullptr; + return; mMaiAtkHyperlink = reinterpret_cast (g_object_new(mai_atk_hyperlink_get_type(), nullptr)); NS_ASSERTION(mMaiAtkHyperlink, "OUT OF MEMORY"); - NS_ENSURE_TRUE(mMaiAtkHyperlink, nullptr); + if (!mMaiAtkHyperlink) + return; - /* be sure to initialize it with "this" */ - MaiHyperlink::Initialize(mMaiAtkHyperlink, this); - - return mMaiAtkHyperlink; + MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = this; } -/* static */ - -/* remember to call this static function when a MaiAtkHyperlink - * is created - */ - -nsresult -MaiHyperlink::Initialize(AtkHyperlink *aObj, MaiHyperlink *aHyperlink) +MaiHyperlink::~MaiHyperlink() { - NS_ENSURE_ARG(MAI_IS_ATK_HYPERLINK(aObj)); - NS_ENSURE_ARG(aHyperlink); - - /* initialize hyperlink */ - MAI_ATK_HYPERLINK(aObj)->maiHyperlink = aHyperlink; - return NS_OK; + if (mMaiAtkHyperlink) { + MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr; + g_object_unref(mMaiAtkHyperlink); + } } + /* static functions for ATK callbacks */ void diff --git a/accessible/atk/nsMaiHyperlink.h b/accessible/atk/nsMaiHyperlink.h index de179366d558..7fca0275eeac 100644 --- a/accessible/atk/nsMaiHyperlink.h +++ b/accessible/atk/nsMaiHyperlink.h @@ -27,15 +27,13 @@ public: ~MaiHyperlink(); public: - AtkHyperlink *GetAtkHyperlink(void); + AtkHyperlink* GetAtkHyperlink() const { return mMaiAtkHyperlink; } Accessible* GetAccHyperlink() { return mHyperlink && mHyperlink->IsLink() ? mHyperlink : nullptr; } protected: Accessible* mHyperlink; AtkHyperlink* mMaiAtkHyperlink; -public: - static nsresult Initialize(AtkHyperlink *aObj, MaiHyperlink *aClass); }; } // namespace a11y diff --git a/accessible/atk/nsMaiInterfaceHyperlinkImpl.cpp b/accessible/atk/nsMaiInterfaceHyperlinkImpl.cpp index 6eff50f435bf..ee6d1969243a 100644 --- a/accessible/atk/nsMaiInterfaceHyperlinkImpl.cpp +++ b/accessible/atk/nsMaiInterfaceHyperlinkImpl.cpp @@ -21,9 +21,7 @@ getHyperlinkCB(AtkHyperlinkImpl* aImpl) NS_ENSURE_TRUE(accWrap->IsLink(), nullptr); - MaiHyperlink* maiHyperlink = accWrap->GetMaiHyperlink(); - NS_ENSURE_TRUE(maiHyperlink, nullptr); - return maiHyperlink->GetAtkHyperlink(); + return MAI_ATK_OBJECT(aImpl)->GetAtkHyperlink(); } } diff --git a/accessible/atk/nsMaiInterfaceHypertext.cpp b/accessible/atk/nsMaiInterfaceHypertext.cpp index bf9bd67d0277..88b500486fae 100644 --- a/accessible/atk/nsMaiInterfaceHypertext.cpp +++ b/accessible/atk/nsMaiInterfaceHypertext.cpp @@ -32,12 +32,9 @@ getLinkCB(AtkHypertext *aText, gint aLinkIndex) } AtkObject* hyperLinkAtkObj = AccessibleWrap::GetAtkObject(hyperLink); - AccessibleWrap* accChild = GetAccessibleWrap(hyperLinkAtkObj); - NS_ENSURE_TRUE(accChild, nullptr); + NS_ENSURE_TRUE(IS_MAI_OBJECT(hyperLinkAtkObj), nullptr); - MaiHyperlink* maiHyperlink = accChild->GetMaiHyperlink(); - NS_ENSURE_TRUE(maiHyperlink, nullptr); - return maiHyperlink->GetAtkHyperlink(); + return MAI_ATK_OBJECT(hyperLinkAtkObj)->GetAtkHyperlink(); } if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { diff --git a/accessible/base/nsCoreUtils.cpp b/accessible/base/nsCoreUtils.cpp index a564f7b65e80..2b427e39efd7 100644 --- a/accessible/base/nsCoreUtils.cpp +++ b/accessible/base/nsCoreUtils.cpp @@ -300,7 +300,7 @@ nsCoreUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame, return; nsPoint point = - aPoint.ToAppUnits(aFrame->PresContext()->AppUnitsPerDevPixel()); + ToAppUnits(aPoint, aFrame->PresContext()->AppUnitsPerDevPixel()); nsRect frameRect = aFrame->GetScreenRectInAppUnits(); nsPoint deltaPoint(point.x - frameRect.x, point.y - frameRect.y); diff --git a/accessible/generic/Accessible.h b/accessible/generic/Accessible.h index f9d909de42e1..10528d347ef5 100644 --- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -15,13 +15,13 @@ #include "nsString.h" #include "nsTArray.h" #include "nsRefPtrHashtable.h" +#include "nsRect.h" struct nsRoleMapEntry; struct nsRect; class nsIFrame; class nsIAtom; -struct nsIntRect; class nsIPersistentProperties; class nsView; diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index bba558296b77..eeef848a4294 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1040,7 +1040,7 @@ HyperTextAccessible::OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType) nsPresContext* presContext = mDoc->PresContext(); nsPoint coordsInAppUnits = - coords.ToAppUnits(presContext->AppUnitsPerDevPixel()); + ToAppUnits(coords, presContext->AppUnitsPerDevPixel()); nsRect frameScreenRect = hyperFrame->GetScreenRectInAppUnits(); if (!frameScreenRect.Contains(coordsInAppUnits.x, coordsInAppUnits.y)) @@ -1568,7 +1568,7 @@ HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset, nsPresContext* presContext = frame->PresContext(); nsPoint coordsInAppUnits = - coords.ToAppUnits(presContext->AppUnitsPerDevPixel()); + ToAppUnits(coords, presContext->AppUnitsPerDevPixel()); bool initialScrolled = false; nsIFrame *parentFrame = frame; diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index 689879254d80..eddd7e64420b 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -8,9 +8,9 @@ include protocol PContent; include "mozilla/GfxMessageUtils.h"; -using struct nsIntPoint from "nsRect.h"; -using struct nsIntRect from "nsRect.h"; +using nsIntRect from "nsRect.h"; using mozilla::gfx::IntSize from "mozilla/gfx/Point.h"; +using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h"; namespace mozilla { namespace a11y { @@ -135,7 +135,7 @@ child: prio(high) sync PasteText(uint64_t aID, int32_t aPosition) returns(bool aValid); - prio(high) sync ImagePosition(uint64_t aID, uint32_t aCoordType) returns(nsIntPoint aRetVal); + prio(high) sync ImagePosition(uint64_t aID, uint32_t aCoordType) returns(IntPoint aRetVal); prio(high) sync ImageSize(uint64_t aID) returns(IntSize aRetVal); prio(high) sync StartOffset(uint64_t aID) returns(uint32_t aRetVal, bool aOk); diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index e078928e8267..6145f16c7d9b 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -134,8 +134,8 @@ - - + + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index e05fe9582495..1e7d3345dc62 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index b285cd96dcee..d2a1b48dc2ae 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,10 +17,10 @@ - + - + @@ -135,7 +135,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index a810837e48bb..1784130dc7e4 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 696e9a50626e..9056c099e737 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index e05fe9582495..1e7d3345dc62 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 0880629d975e..83ef3fe42246 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -146,7 +146,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 38ccf41040cb..23894ef1b705 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,10 +17,10 @@ - + - + @@ -145,7 +145,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 354df4d890fb..451e3dd62393 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "0645bbed4d6cbd8064652eebafe011edc3e417fd", + "git_revision": "15134b080b5f406e5aa36f5136c17dafb4e31f64", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "b8a031b1d0d2dfe6dc33194ec18b25c6f0cd625a", + "revision": "457b84a122653f399cb817513b5149c4c087afe9", "repo_path": "integration/gaia-central" } diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 229a87c5546f..1fe4f77d08f7 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,10 +17,10 @@ - + - + @@ -130,7 +130,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 680fc7e3a6f2..9974a71f4aac 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -156,5 +156,5 @@ - + diff --git a/config/config.mk b/config/config.mk index 50979bd4c16d..b3760d2f13e7 100644 --- a/config/config.mk +++ b/config/config.mk @@ -298,11 +298,6 @@ MY_RULES := $(DEPTH)/config/myrules.mk # CCC = $(CXX) -# Java macros -JAVA_GEN_DIR = _javagen -JAVA_DIST_DIR = $(DEPTH)/$(JAVA_GEN_DIR) -JAVA_IFACES_PKG_NAME = org/mozilla/interfaces - INCLUDES = \ -I$(srcdir) \ -I. \ diff --git a/docshell/base/nsIContentViewer.idl b/docshell/base/nsIContentViewer.idl index 63c7aeb5b3d5..507a5f41e27f 100644 --- a/docshell/base/nsIContentViewer.idl +++ b/docshell/base/nsIContentViewer.idl @@ -14,9 +14,9 @@ interface nsIPrintSettings; %{ C++ #include "nsTArray.h" +#include "nsRect.h" class nsIWidget; -struct nsIntRect; class nsIPresShell; class nsPresContext; class nsView; diff --git a/docshell/shistory/public/nsISHEntry.idl b/docshell/shistory/public/nsISHEntry.idl index e36c7b6cf361..3e29e8be32ff 100644 --- a/docshell/shistory/public/nsISHEntry.idl +++ b/docshell/shistory/public/nsISHEntry.idl @@ -22,7 +22,7 @@ interface nsIStructuredCloneContainer; interface nsIBFCacheEntry; %{C++ -struct nsIntRect; +#include "nsRect.h" class nsDocShellEditorData; class nsSHEntryShared; %} diff --git a/docshell/test/iframesandbox/mochitest.ini b/docshell/test/iframesandbox/mochitest.ini index 574278f02199..899feffb26ac 100644 --- a/docshell/test/iframesandbox/mochitest.ini +++ b/docshell/test/iframesandbox/mochitest.ini @@ -15,6 +15,6 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #bug 948948, NS_ERROR_FAILURE [test_parent_navigation_by_location.html] [test_sibling_navigation_by_location.html] [test_top_navigation_by_location_exotic.html] -skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt +skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || android_version == '18' #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt [test_top_navigation_by_location.html] -skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt +skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || android_version == '18' #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index c7d49ccee5ab..7d5a5fc65b15 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -3922,6 +3922,42 @@ nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks) mFrameRequestCallbacks.Clear(); } +bool +nsIDocument::ShouldThrottleFrameRequests() +{ + if (!mIsShowing) { + // We're not showing (probably in a background tab or the bf cache). + return true; + } + + if (!mPresShell) { + return false; // Can't do anything smarter. + } + + nsIFrame* frame = mPresShell->GetRootFrame(); + if (!frame) { + return false; // Can't do anything smarter. + } + + nsIFrame* displayRootFrame = nsLayoutUtils::GetDisplayRootFrame(frame); + if (!displayRootFrame) { + return false; // Can't do anything smarter. + } + + if (!displayRootFrame->DidPaintPresShell(mPresShell)) { + // We didn't get painted during the last paint, so we're not visible. + // Throttle. Note that because we have to paint this document at least + // once to unthrottle it, we will drop one requestAnimationFrame frame + // when a document that previously wasn't visible scrolls into view. This + // is acceptable since it would happen outside the viewport on APZ + // platforms and is unlikely to be human-perceivable on non-APZ platforms. + return true; + } + + // We got painted during the last paint, so run at full speed. + return false; +} + PLDHashOperator RequestDiscardEnumerator(imgIRequest* aKey, uint32_t aData, void* userArg) diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 8121d8a37e8c..52686f803058 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2104,6 +2104,13 @@ public: */ void TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks); + /** + * @return true if this document's frame request callbacks should be + * throttled. We throttle requestAnimationFrame for documents which aren't + * visible (e.g. scrolled out of the viewport). + */ + bool ShouldThrottleFrameRequests(); + // This returns true when the document tree is being teared down. bool InUnlinkOrDeletion() { return mInUnlinkOrDeletion; } diff --git a/dom/bluetooth/BluetoothCommon.h b/dom/bluetooth/BluetoothCommon.h index 6152b5822584..cf1a5fd2e17a 100644 --- a/dom/bluetooth/BluetoothCommon.h +++ b/dom/bluetooth/BluetoothCommon.h @@ -235,10 +235,16 @@ extern bool gBluetoothDebugFlag; /** * When a remote BLE device gets connected / disconnected, we'll dispatch an - * event + * event. */ #define GATT_CONNECTION_STATE_CHANGED_ID "connectionstatechanged" +/** + * When attributes of BluetoothManager, BluetoothAdapter, or BluetoothDevice + * are changed, we'll dispatch an event. + */ +#define ATTRIBUTE_CHANGED_ID "attributechanged" + // Bluetooth address format: xx:xx:xx:xx:xx:xx (or xx_xx_xx_xx_xx_xx) #define BLUETOOTH_ADDRESS_LENGTH 17 #define BLUETOOTH_ADDRESS_NONE "00:00:00:00:00:00" diff --git a/dom/bluetooth/BluetoothSocketObserver.h b/dom/bluetooth/BluetoothSocketObserver.h index 6a2d6f89bad7..6135440b9682 100644 --- a/dom/bluetooth/BluetoothSocketObserver.h +++ b/dom/bluetooth/BluetoothSocketObserver.h @@ -8,7 +8,7 @@ #define mozilla_dom_bluetooth_BluetoothSocketObserver_h #include "BluetoothCommon.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" BEGIN_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluedroid/BluetoothOppManager.h b/dom/bluetooth/bluedroid/BluetoothOppManager.h index 596c04cfa998..4128a2c15dc9 100644 --- a/dom/bluetooth/bluedroid/BluetoothOppManager.h +++ b/dom/bluetooth/bluedroid/BluetoothOppManager.h @@ -11,7 +11,7 @@ #include "BluetoothProfileManagerBase.h" #include "BluetoothSocketObserver.h" #include "DeviceStorage.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" #include "nsCOMArray.h" class nsIDOMBlob; diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index 947b256eb031..028eedf928ca 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -36,7 +36,7 @@ #include "BluetoothUtils.h" #include "BluetoothUuid.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" #include "mozilla/StaticMutex.h" #include "mozilla/StaticPtr.h" #include "mozilla/unused.h" diff --git a/dom/bluetooth/bluedroid/BluetoothSocket.cpp b/dom/bluetooth/bluedroid/BluetoothSocket.cpp index 09080cdffd99..2a3caeb78e19 100644 --- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp +++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp @@ -13,6 +13,7 @@ #include "BluetoothSocketObserver.h" #include "BluetoothInterface.h" #include "BluetoothUtils.h" +#include "mozilla/ipc/UnixSocketWatcher.h" #include "mozilla/FileUtils.h" #include "mozilla/RefPtr.h" #include "nsThreadUtils.h" diff --git a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h index 8bfc06125c79..6b26af15cd69 100644 --- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h +++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h @@ -12,7 +12,7 @@ #include "BluetoothHfpManagerBase.h" #include "BluetoothRilListener.h" #include "BluetoothSocketObserver.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" #include "mozilla/Hal.h" BEGIN_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluetooth1/BluetoothService.cpp b/dom/bluetooth/bluetooth1/BluetoothService.cpp index 57afeb4f6199..a068e5d72b1c 100644 --- a/dom/bluetooth/bluetooth1/BluetoothService.cpp +++ b/dom/bluetooth/bluetooth1/BluetoothService.cpp @@ -28,7 +28,7 @@ #include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/dom/ipc/BlobChild.h" #include "mozilla/dom/ipc/BlobParent.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" #include "nsContentUtils.h" #include "nsIObserverService.h" #include "nsISettingsService.h" diff --git a/dom/bluetooth/bluetooth1/BluetoothService.h b/dom/bluetooth/bluetooth1/BluetoothService.h index f7a92109c734..72e8c115b740 100644 --- a/dom/bluetooth/bluetooth1/BluetoothService.h +++ b/dom/bluetooth/bluetooth1/BluetoothService.h @@ -23,9 +23,6 @@ namespace dom { class BlobChild; class BlobParent; } -namespace ipc { -class UnixSocketConsumer; -} } BEGIN_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.h b/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.h index 7e80b25918ba..abad0d1b5d46 100644 --- a/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.h +++ b/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.h @@ -9,22 +9,10 @@ #include "BluetoothService.h" -namespace mozilla { -namespace ipc { -class UnixSocketConsumer; -} -namespace dom { -namespace bluetooth { +BEGIN_BLUETOOTH_NAMESPACE class BluetoothChild; -} // namespace bluetooth -} // namespace dom -} // namespace mozilla - - -BEGIN_BLUETOOTH_NAMESPACE - class BluetoothServiceChildProcess : public BluetoothService { friend class mozilla::dom::bluetooth::BluetoothChild; diff --git a/dom/bluetooth/bluetooth2/BluetoothAdapter.cpp b/dom/bluetooth/bluetooth2/BluetoothAdapter.cpp index cebeeec67843..f4bebb12ad6d 100644 --- a/dom/bluetooth/bluetooth2/BluetoothAdapter.cpp +++ b/dom/bluetooth/bluetooth2/BluetoothAdapter.cpp @@ -791,7 +791,7 @@ BluetoothAdapter::SetAdapterState(BluetoothAdapterState aState) mState = aState; // Fire BluetoothAttributeEvent for changed adapter state - nsTArray types; + Sequence types; BT_APPEND_ENUM_STRING(types, BluetoothAdapterAttribute, BluetoothAdapterAttribute::State); @@ -806,7 +806,7 @@ BluetoothAdapter::HandlePropertyChanged(const BluetoothValue& aValue) const InfallibleTArray& arr = aValue.get_ArrayOfBluetoothNamedValue(); - nsTArray types; + Sequence types; for (uint32_t i = 0, propCount = arr.Length(); i < propCount; ++i) { BluetoothAdapterAttribute type = ConvertStringToAdapterAttribute(arr[i].name()); @@ -912,26 +912,17 @@ BluetoothAdapter::HandleDeviceUnpaired(const BluetoothValue& aValue) } void -BluetoothAdapter::DispatchAttributeEvent(const nsTArray& aTypes) +BluetoothAdapter::DispatchAttributeEvent(const Sequence& aTypes) { NS_ENSURE_TRUE_VOID(aTypes.Length()); - AutoJSAPI jsapi; - NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner())); - JSContext* cx = jsapi.cx(); - JS::Rooted value(cx); + BluetoothAttributeEventInit init; + init.mAttrs = aTypes; - if (!ToJSValue(cx, aTypes, &value)) { - JS_ClearPendingException(cx); - return; - } - - RootedDictionary init(cx); - init.mAttrs = value; nsRefPtr event = - BluetoothAttributeEvent::Constructor(this, - NS_LITERAL_STRING("attributechanged"), - init); + BluetoothAttributeEvent::Constructor( + this, NS_LITERAL_STRING(ATTRIBUTE_CHANGED_ID), init); + DispatchTrustedEvent(event); } diff --git a/dom/bluetooth/bluetooth2/BluetoothAdapter.h b/dom/bluetooth/bluetooth2/BluetoothAdapter.h index 2e164297d4a8..9029e2591adb 100644 --- a/dom/bluetooth/bluetooth2/BluetoothAdapter.h +++ b/dom/bluetooth/bluetooth2/BluetoothAdapter.h @@ -253,7 +253,7 @@ private: /** * Fire BluetoothAttributeEvent to trigger onattributechanged event handler. */ - void DispatchAttributeEvent(const nsTArray& aTypes); + void DispatchAttributeEvent(const Sequence& aTypes); /** * Fire BluetoothDeviceEvent to trigger diff --git a/dom/bluetooth/bluetooth2/BluetoothDevice.cpp b/dom/bluetooth/bluetooth2/BluetoothDevice.cpp index 9e31fb64d2aa..8ea1d7bb1b45 100644 --- a/dom/bluetooth/bluetooth2/BluetoothDevice.cpp +++ b/dom/bluetooth/bluetooth2/BluetoothDevice.cpp @@ -261,7 +261,7 @@ BluetoothDevice::HandlePropertyChanged(const BluetoothValue& aValue) const InfallibleTArray& arr = aValue.get_ArrayOfBluetoothNamedValue(); - nsTArray types; + Sequence types; for (uint32_t i = 0, propCount = arr.Length(); i < propCount; ++i) { BluetoothDeviceAttribute type = ConvertStringToDeviceAttribute(arr[i].name()); @@ -283,26 +283,16 @@ BluetoothDevice::HandlePropertyChanged(const BluetoothValue& aValue) } void -BluetoothDevice::DispatchAttributeEvent(const nsTArray& aTypes) +BluetoothDevice::DispatchAttributeEvent(const Sequence& aTypes) { NS_ENSURE_TRUE_VOID(aTypes.Length()); - AutoJSAPI jsapi; - NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner())); - JSContext* cx = jsapi.cx(); - JS::Rooted value(cx); - - if (!ToJSValue(cx, aTypes, &value)) { - JS_ClearPendingException(cx); - return; - } - - RootedDictionary init(cx); - init.mAttrs = value; + BluetoothAttributeEventInit init; + init.mAttrs = aTypes; nsRefPtr event = - BluetoothAttributeEvent::Constructor(this, - NS_LITERAL_STRING("attributechanged"), - init); + BluetoothAttributeEvent::Constructor( + this, NS_LITERAL_STRING(ATTRIBUTE_CHANGED_ID), init); + DispatchTrustedEvent(event); } diff --git a/dom/bluetooth/bluetooth2/BluetoothDevice.h b/dom/bluetooth/bluetooth2/BluetoothDevice.h index 7dc40f981f3b..59c460459b35 100644 --- a/dom/bluetooth/bluetooth2/BluetoothDevice.h +++ b/dom/bluetooth/bluetooth2/BluetoothDevice.h @@ -119,7 +119,7 @@ private: /** * Fire BluetoothAttributeEvent to trigger onattributechanged event handler. */ - void DispatchAttributeEvent(const nsTArray& aTypes); + void DispatchAttributeEvent(const Sequence& aTypes); /** * Convert uint32_t to BluetoothDeviceType. diff --git a/dom/bluetooth/bluetooth2/BluetoothManager.cpp b/dom/bluetooth/bluetooth2/BluetoothManager.cpp index ebb42c89eebc..a4167e33f4fc 100644 --- a/dom/bluetooth/bluetooth2/BluetoothManager.cpp +++ b/dom/bluetooth/bluetooth2/BluetoothManager.cpp @@ -246,28 +246,18 @@ BluetoothManager::DispatchAttributeEvent() MOZ_ASSERT(NS_IsMainThread()); BT_API2_LOGR(); - AutoJSAPI jsapi; - NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner())); - JSContext* cx = jsapi.cx(); - JS::Rooted value(cx); - - nsTArray types; + Sequence types; BT_APPEND_ENUM_STRING(types, BluetoothManagerAttribute, BluetoothManagerAttribute::DefaultAdapter); - if (!ToJSValue(cx, types, &value)) { - JS_ClearPendingException(cx); - return; - } - // Notify application of default adapter change - RootedDictionary init(cx); - init.mAttrs = value; + BluetoothAttributeEventInit init; + init.mAttrs = types; nsRefPtr event = - BluetoothAttributeEvent::Constructor(this, - NS_LITERAL_STRING("attributechanged"), - init); + BluetoothAttributeEvent::Constructor( + this, NS_LITERAL_STRING(ATTRIBUTE_CHANGED_ID), init); + DispatchTrustedEvent(event); } diff --git a/dom/bluetooth/bluetooth2/BluetoothService.h b/dom/bluetooth/bluetooth2/BluetoothService.h index 7e566cedf6bb..b3f33255c23e 100644 --- a/dom/bluetooth/bluetooth2/BluetoothService.h +++ b/dom/bluetooth/bluetooth2/BluetoothService.h @@ -24,9 +24,6 @@ namespace dom { class BlobChild; class BlobParent; } -namespace ipc { -class UnixSocketConsumer; -} } BEGIN_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h b/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h index 8634a131166a..22753bc13770 100644 --- a/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h +++ b/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h @@ -9,22 +9,10 @@ #include "BluetoothService.h" -namespace mozilla { -namespace ipc { -class UnixSocketConsumer; -} -namespace dom { -namespace bluetooth { +BEGIN_BLUETOOTH_NAMESPACE class BluetoothChild; -} // namespace bluetooth -} // namespace dom -} // namespace mozilla - - -BEGIN_BLUETOOTH_NAMESPACE - class BluetoothServiceChildProcess : public BluetoothService { friend class mozilla::dom::bluetooth::BluetoothChild; diff --git a/dom/bluetooth/bluez/BluetoothDBusService.cpp b/dom/bluetooth/bluez/BluetoothDBusService.cpp index b0795ea6fb86..f22bd43efda5 100644 --- a/dom/bluetooth/bluez/BluetoothDBusService.cpp +++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp @@ -40,7 +40,7 @@ #include "mozilla/ClearOnShutdown.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/Hal.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" #include "mozilla/ipc/DBusUtils.h" #include "mozilla/ipc/RawDBusConnection.h" #include "mozilla/LazyIdleThread.h" diff --git a/dom/bluetooth/bluez/BluetoothHfpManager.h b/dom/bluetooth/bluez/BluetoothHfpManager.h index 20b9d81540e8..e107ed9ff451 100644 --- a/dom/bluetooth/bluez/BluetoothHfpManager.h +++ b/dom/bluetooth/bluez/BluetoothHfpManager.h @@ -13,7 +13,7 @@ #include "BluetoothRilListener.h" #endif #include "BluetoothSocketObserver.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" #include "mozilla/Hal.h" BEGIN_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluez/BluetoothOppManager.h b/dom/bluetooth/bluez/BluetoothOppManager.h index 9d1898f84edf..01250002cae6 100644 --- a/dom/bluetooth/bluez/BluetoothOppManager.h +++ b/dom/bluetooth/bluez/BluetoothOppManager.h @@ -11,7 +11,7 @@ #include "BluetoothProfileManagerBase.h" #include "BluetoothSocketObserver.h" #include "DeviceStorage.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" #include "nsCOMArray.h" class nsIDOMBlob; diff --git a/dom/bluetooth/bluez/BluetoothSocket.cpp b/dom/bluetooth/bluez/BluetoothSocket.cpp index ce821052d7e4..f92f7434b782 100644 --- a/dom/bluetooth/bluez/BluetoothSocket.cpp +++ b/dom/bluetooth/bluez/BluetoothSocket.cpp @@ -5,13 +5,544 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "BluetoothSocket.h" - +#include #include "BluetoothSocketObserver.h" #include "BluetoothUnixSocketConnector.h" +#include "mozilla/unused.h" +#include "nsTArray.h" #include "nsThreadUtils.h" +#include "nsXULAppAPI.h" using namespace mozilla::ipc; -USING_BLUETOOTH_NAMESPACE + +BEGIN_BLUETOOTH_NAMESPACE + +static const size_t MAX_READ_SIZE = 1 << 16; + +// +// BluetoothSocketIO +// + +class BluetoothSocket::BluetoothSocketIO final + : public UnixSocketWatcher + , protected SocketIOBase +{ +public: + BluetoothSocketIO(MessageLoop* mIOLoop, + BluetoothSocket* aConsumer, + UnixSocketConnector* aConnector, + const nsACString& aAddress); + ~BluetoothSocketIO(); + + void GetSocketAddr(nsAString& aAddrStr) const; + SocketConsumerBase* GetConsumer(); + SocketBase* GetSocketBase(); + + // Shutdown state + // + + bool IsShutdownOnMainThread() const; + void ShutdownOnMainThread(); + + bool IsShutdownOnIOThread() const; + void ShutdownOnIOThread(); + + // Delayed-task handling + // + + void SetDelayedConnectTask(CancelableTask* aTask); + void ClearDelayedConnectTask(); + void CancelDelayedConnectTask(); + + // Task callback methods + // + + /** + * Run bind/listen to prepare for further runs of accept() + */ + void Listen(); + + /** + * Connect to a socket + */ + void Connect(); + + void Send(UnixSocketRawData* aData); + + // I/O callback methods + // + + void OnAccepted(int aFd, const sockaddr_any* aAddr, + socklen_t aAddrLen) override; + void OnConnected() override; + void OnError(const char* aFunction, int aErrno) override; + void OnListening() override; + void OnSocketCanReceiveWithoutBlocking() override; + void OnSocketCanSendWithoutBlocking() override; + +private: + void FireSocketError(); + + // Set up flags on file descriptor. + static bool SetSocketFlags(int aFd); + + /** + * Consumer pointer. Non-thread safe RefPtr, so should only be manipulated + * directly from main thread. All non-main-thread accesses should happen with + * mIO as container. + */ + RefPtr mConsumer; + + /** + * Connector object used to create the connection we are currently using. + */ + nsAutoPtr mConnector; + + /** + * If true, do not requeue whatever task we're running + */ + bool mShuttingDownOnIOThread; + + /** + * Address we are connecting to, assuming we are creating a client connection. + */ + nsCString mAddress; + + /** + * Size of the socket address struct + */ + socklen_t mAddrSize; + + /** + * Address struct of the socket currently in use + */ + sockaddr_any mAddr; + + /** + * Task member for delayed connect task. Should only be access on main thread. + */ + CancelableTask* mDelayedConnectTask; +}; + +BluetoothSocket::BluetoothSocketIO::BluetoothSocketIO( + MessageLoop* mIOLoop, + BluetoothSocket* aConsumer, + UnixSocketConnector* aConnector, + const nsACString& aAddress) + : UnixSocketWatcher(mIOLoop) + , SocketIOBase(MAX_READ_SIZE) + , mConsumer(aConsumer) + , mConnector(aConnector) + , mShuttingDownOnIOThread(false) + , mAddress(aAddress) + , mDelayedConnectTask(nullptr) +{ + MOZ_ASSERT(mConsumer); + MOZ_ASSERT(mConnector); +} + +BluetoothSocket::BluetoothSocketIO::~BluetoothSocketIO() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(IsShutdownOnMainThread()); +} + +void +BluetoothSocket::BluetoothSocketIO::GetSocketAddr(nsAString& aAddrStr) const +{ + if (!mConnector) { + NS_WARNING("No connector to get socket address from!"); + aAddrStr.Truncate(); + return; + } + mConnector->GetSocketAddr(mAddr, aAddrStr); +} + +SocketConsumerBase* +BluetoothSocket::BluetoothSocketIO::GetConsumer() +{ + return mConsumer.get(); +} + +SocketBase* +BluetoothSocket::BluetoothSocketIO::GetSocketBase() +{ + return GetConsumer(); +} + +bool +BluetoothSocket::BluetoothSocketIO::IsShutdownOnMainThread() const +{ + MOZ_ASSERT(NS_IsMainThread()); + + return mConsumer == nullptr; +} + +void +BluetoothSocket::BluetoothSocketIO::ShutdownOnMainThread() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!IsShutdownOnMainThread()); + + mConsumer = nullptr; +} + +bool +BluetoothSocket::BluetoothSocketIO::IsShutdownOnIOThread() const +{ + return mShuttingDownOnIOThread; +} + +void +BluetoothSocket::BluetoothSocketIO::ShutdownOnIOThread() +{ + MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(!mShuttingDownOnIOThread); + + Close(); // will also remove fd from I/O loop + mShuttingDownOnIOThread = true; +} + +void +BluetoothSocket::BluetoothSocketIO::SetDelayedConnectTask(CancelableTask* aTask) +{ + MOZ_ASSERT(NS_IsMainThread()); + + mDelayedConnectTask = aTask; +} + +void +BluetoothSocket::BluetoothSocketIO::ClearDelayedConnectTask() +{ + MOZ_ASSERT(NS_IsMainThread()); + + mDelayedConnectTask = nullptr; +} + +void +BluetoothSocket::BluetoothSocketIO::CancelDelayedConnectTask() +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (!mDelayedConnectTask) { + return; + } + + mDelayedConnectTask->Cancel(); + ClearDelayedConnectTask(); +} + +void +BluetoothSocket::BluetoothSocketIO::Listen() +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + MOZ_ASSERT(mConnector); + + // This will set things we don't particularly care about, but it will hand + // back the correct structure size which is what we do care about. + if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) { + NS_WARNING("Cannot create socket address!"); + FireSocketError(); + return; + } + + if (!IsOpen()) { + int fd = mConnector->Create(); + if (fd < 0) { + NS_WARNING("Cannot create socket fd!"); + FireSocketError(); + return; + } + if (!SetSocketFlags(fd)) { + NS_WARNING("Cannot set socket flags!"); + FireSocketError(); + return; + } + SetFd(fd); + + // calls OnListening on success, or OnError otherwise + nsresult rv = UnixSocketWatcher::Listen( + reinterpret_cast(&mAddr), mAddrSize); + NS_WARN_IF(NS_FAILED(rv)); + } +} + +void +BluetoothSocket::BluetoothSocketIO::Connect() +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + MOZ_ASSERT(mConnector); + + if (!IsOpen()) { + int fd = mConnector->Create(); + if (fd < 0) { + NS_WARNING("Cannot create socket fd!"); + FireSocketError(); + return; + } + if (!SetSocketFlags(fd)) { + NS_WARNING("Cannot set socket flags!"); + FireSocketError(); + return; + } + SetFd(fd); + } + + if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) { + NS_WARNING("Cannot create socket address!"); + FireSocketError(); + return; + } + + // calls OnConnected() on success, or OnError() otherwise + nsresult rv = UnixSocketWatcher::Connect( + reinterpret_cast(&mAddr), mAddrSize); + NS_WARN_IF(NS_FAILED(rv)); +} + +void +BluetoothSocket::BluetoothSocketIO::Send(UnixSocketRawData* aData) +{ + EnqueueData(aData); + AddWatchers(WRITE_WATCHER, false); +} + +void +BluetoothSocket::BluetoothSocketIO::OnAccepted( + int aFd, const sockaddr_any* aAddr, socklen_t aAddrLen) +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING); + MOZ_ASSERT(aAddr); + MOZ_ASSERT(aAddrLen > 0 && (size_t)aAddrLen <= sizeof(mAddr)); + + memcpy (&mAddr, aAddr, aAddrLen); + mAddrSize = aAddrLen; + + if (!mConnector->SetUp(aFd)) { + NS_WARNING("Could not set up socket!"); + return; + } + + RemoveWatchers(READ_WATCHER|WRITE_WATCHER); + Close(); + if (!SetSocketFlags(aFd)) { + return; + } + SetSocket(aFd, SOCKET_IS_CONNECTED); + + nsRefPtr r = + new SocketIOEventRunnable( + this, SocketIOEventRunnable::CONNECT_SUCCESS); + NS_DispatchToMainThread(r); + + AddWatchers(READ_WATCHER, true); + if (HasPendingData()) { + AddWatchers(WRITE_WATCHER, false); + } +} + +void +BluetoothSocket::BluetoothSocketIO::OnConnected() +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); + + if (!SetSocketFlags(GetFd())) { + NS_WARNING("Cannot set socket flags!"); + FireSocketError(); + return; + } + + if (!mConnector->SetUp(GetFd())) { + NS_WARNING("Could not set up socket!"); + FireSocketError(); + return; + } + + nsRefPtr r = + new SocketIOEventRunnable( + this, SocketIOEventRunnable::CONNECT_SUCCESS); + NS_DispatchToMainThread(r); + + AddWatchers(READ_WATCHER, true); + if (HasPendingData()) { + AddWatchers(WRITE_WATCHER, false); + } +} + +void +BluetoothSocket::BluetoothSocketIO::OnListening() +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING); + + if (!mConnector->SetUpListenSocket(GetFd())) { + NS_WARNING("Could not set up listen socket!"); + FireSocketError(); + return; + } + + AddWatchers(READ_WATCHER, true); +} + +void +BluetoothSocket::BluetoothSocketIO::OnError(const char* aFunction, int aErrno) +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + + UnixFdWatcher::OnError(aFunction, aErrno); + FireSocketError(); +} + +void +BluetoothSocket::BluetoothSocketIO::OnSocketCanReceiveWithoutBlocking() +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984 + + ssize_t res = ReceiveData(GetFd(), this); + if (res < 0) { + /* I/O error */ + RemoveWatchers(READ_WATCHER|WRITE_WATCHER); + } else if (!res) { + /* EOF or peer shutdown */ + RemoveWatchers(READ_WATCHER); + } +} + +void +BluetoothSocket::BluetoothSocketIO::OnSocketCanSendWithoutBlocking() +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984 + + nsresult rv = SendPendingData(GetFd(), this); + if (NS_FAILED(rv)) { + return; + } + + if (HasPendingData()) { + AddWatchers(WRITE_WATCHER, false); + } +} + +void +BluetoothSocket::BluetoothSocketIO::FireSocketError() +{ + MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); + + // Clean up watchers, statuses, fds + Close(); + + // Tell the main thread we've errored + nsRefPtr r = + new SocketIOEventRunnable( + this, SocketIOEventRunnable::CONNECT_ERROR); + + NS_DispatchToMainThread(r); +} + +bool +BluetoothSocket::BluetoothSocketIO::SetSocketFlags(int aFd) +{ + // Set socket addr to be reused even if kernel is still waiting to close + int n = 1; + if (setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) < 0) { + return false; + } + + // Set close-on-exec bit. + int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD)); + if (-1 == flags) { + return false; + } + flags |= FD_CLOEXEC; + if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) { + return false; + } + + // Set non-blocking status flag. + flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL)); + if (-1 == flags) { + return false; + } + flags |= O_NONBLOCK; + if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) { + return false; + } + + return true; +} + +// +// Socket tasks +// + +class BluetoothSocket::ListenTask final + : public SocketIOTask +{ +public: + ListenTask(BluetoothSocketIO* aIO) + : SocketIOTask(aIO) + { } + + void Run() override + { + MOZ_ASSERT(!NS_IsMainThread()); + + if (!IsCanceled()) { + GetIO()->Listen(); + } + } +}; + +class BluetoothSocket::ConnectTask final + : public SocketIOTask +{ +public: + ConnectTask(BluetoothSocketIO* aIO) + : SocketIOTask(aIO) + { } + + void Run() override + { + MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(!IsCanceled()); + + GetIO()->Connect(); + } +}; + +class BluetoothSocket::DelayedConnectTask final + : public SocketIOTask +{ +public: + DelayedConnectTask(BluetoothSocketIO* aIO) + : SocketIOTask(aIO) + { } + + void Run() override + { + MOZ_ASSERT(NS_IsMainThread()); + + if (IsCanceled()) { + return; + } + + BluetoothSocketIO* io = GetIO(); + if (io->IsShutdownOnMainThread()) { + return; + } + + io->ClearDelayedConnectTask(); + XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ConnectTask(io)); + } +}; + +// +// BluetoothSocket +// BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver, BluetoothSocketType aType, @@ -21,10 +552,16 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver, , mType(aType) , mAuth(aAuth) , mEncrypt(aEncrypt) + , mIO(nullptr) { MOZ_ASSERT(aObserver); } +BluetoothSocket::~BluetoothSocket() +{ + MOZ_ASSERT(!mIO); +} + bool BluetoothSocket::Connect(const nsAString& aDeviceAddress, const BluetoothUuid& aServiceUuid, @@ -101,3 +638,122 @@ BluetoothSocket::OnDisconnect() mObserver->OnSocketDisconnect(this); } +bool +BluetoothSocket::SendSocketData(UnixSocketRawData* aData) +{ + MOZ_ASSERT(NS_IsMainThread()); + if (!mIO) { + return false; + } + + MOZ_ASSERT(!mIO->IsShutdownOnMainThread()); + XRE_GetIOMessageLoop()->PostTask( + FROM_HERE, + new SocketIOSendTask(mIO, aData)); + + return true; +} + +bool +BluetoothSocket::SendSocketData(const nsACString& aStr) +{ + if (aStr.Length() > MAX_READ_SIZE) { + return false; + } + + nsAutoPtr data( + new UnixSocketRawData(aStr.BeginReading(), aStr.Length())); + + if (!SendSocketData(data)) { + return false; + } + + unused << data.forget(); + + return true; +} + +void +BluetoothSocket::CloseSocket() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (!mIO) { + return; + } + + mIO->CancelDelayedConnectTask(); + + // From this point on, we consider mIO as being deleted. + // We sever the relationship here so any future calls to listen or connect + // will create a new implementation. + mIO->ShutdownOnMainThread(); + + XRE_GetIOMessageLoop()->PostTask( + FROM_HERE, new SocketIOShutdownTask(mIO)); + + mIO = nullptr; + + NotifyDisconnect(); +} + +void +BluetoothSocket::GetSocketAddr(nsAString& aAddrStr) +{ + aAddrStr.Truncate(); + if (!mIO || GetConnectionStatus() != SOCKET_CONNECTED) { + NS_WARNING("No socket currently open!"); + return; + } + mIO->GetSocketAddr(aAddrStr); +} + +bool +BluetoothSocket::ConnectSocket(BluetoothUnixSocketConnector* aConnector, + const char* aAddress, + int aDelayMs) +{ + MOZ_ASSERT(aConnector); + MOZ_ASSERT(NS_IsMainThread()); + + nsAutoPtr connector(aConnector); + + if (mIO) { + NS_WARNING("Socket already connecting/connected!"); + return false; + } + + nsCString addr(aAddress); + MessageLoop* ioLoop = XRE_GetIOMessageLoop(); + mIO = new BluetoothSocketIO(ioLoop, this, connector.forget(), addr); + SetConnectionStatus(SOCKET_CONNECTING); + if (aDelayMs > 0) { + DelayedConnectTask* connectTask = new DelayedConnectTask(mIO); + mIO->SetDelayedConnectTask(connectTask); + MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs); + } else { + ioLoop->PostTask(FROM_HERE, new ConnectTask(mIO)); + } + return true; +} + +bool +BluetoothSocket::ListenSocket(BluetoothUnixSocketConnector* aConnector) +{ + MOZ_ASSERT(aConnector); + MOZ_ASSERT(NS_IsMainThread()); + + nsAutoPtr connector(aConnector); + + if (mIO) { + NS_WARNING("Socket already connecting/connected!"); + return false; + } + + mIO = new BluetoothSocketIO( + XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString()); + SetConnectionStatus(SOCKET_LISTENING); + XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ListenTask(mIO)); + return true; +} + +END_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluez/BluetoothSocket.h b/dom/bluetooth/bluez/BluetoothSocket.h index d09be297142c..9cb651f5a208 100644 --- a/dom/bluetooth/bluez/BluetoothSocket.h +++ b/dom/bluetooth/bluez/BluetoothSocket.h @@ -8,19 +8,27 @@ #define mozilla_dom_bluetooth_BluetoothSocket_h #include "BluetoothCommon.h" -#include "mozilla/ipc/UnixSocket.h" +#include +#include "mozilla/ipc/SocketBase.h" +#include "mozilla/ipc/UnixSocketWatcher.h" +#include "mozilla/RefPtr.h" +#include "nsAutoPtr.h" +#include "nsString.h" +#include "nsThreadUtils.h" BEGIN_BLUETOOTH_NAMESPACE class BluetoothSocketObserver; +class BluetoothUnixSocketConnector; -class BluetoothSocket : public mozilla::ipc::UnixSocketConsumer +class BluetoothSocket final : public mozilla::ipc::SocketConsumerBase { public: BluetoothSocket(BluetoothSocketObserver* aObserver, BluetoothSocketType aType, bool aAuth, bool aEncrypt); + ~BluetoothSocket(); bool Connect(const nsAString& aDeviceAddress, const BluetoothUuid& aServiceUuid, @@ -44,11 +52,73 @@ public: GetSocketAddr(aDeviceAddress); } + /** + * Queue data to be sent to the socket on the IO thread. Can only be called on + * originating thread. + * + * @param aMessage Data to be sent to socket + * + * @return true if data is queued, false otherwise (i.e. not connected) + */ + bool SendSocketData(mozilla::ipc::UnixSocketRawData* aMessage); + + /** + * Convenience function for sending strings to the socket (common in bluetooth + * profile usage). Converts to a UnixSocketRawData struct. Can only be called + * on originating thread. + * + * @param aMessage String to be sent to socket + * + * @return true if data is queued, false otherwise (i.e. not connected) + */ + bool SendSocketData(const nsACString& aMessage); + + /** + * Starts a task on the socket that will try to connect to a socket in a + * non-blocking manner. + * + * @param aConnector Connector object for socket type specific functions + * @param aAddress Address to connect to. + * @param aDelayMs Time delay in milli-seconds. + * + * @return true on connect task started, false otherwise. + */ + bool ConnectSocket(BluetoothUnixSocketConnector* aConnector, + const char* aAddress, + int aDelayMs = 0); + + /** + * Starts a task on the socket that will try to accept a new connection in a + * non-blocking manner. + * + * @param aConnector Connector object for socket type specific functions + * + * @return true on listen started, false otherwise + */ + bool ListenSocket(BluetoothUnixSocketConnector* aConnector); + + /** + * Queues the internal representation of socket for deletion. Can be called + * from main thread. + */ + void CloseSocket(); + + /** + * Get the current sockaddr for the socket + */ + void GetSocketAddr(nsAString& aAddrStr); + private: + class BluetoothSocketIO; + class ConnectTask; + class DelayedConnectTask; + class ListenTask; + BluetoothSocketObserver* mObserver; BluetoothSocketType mType; bool mAuth; bool mEncrypt; + BluetoothSocketIO* mIO; }; END_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h index 7c3d0a27c4eb..bb2de7662d52 100644 --- a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h +++ b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h @@ -9,7 +9,7 @@ #include "BluetoothCommon.h" #include -#include +#include BEGIN_BLUETOOTH_NAMESPACE diff --git a/dom/browser-element/mochitest/mochitest-oop.ini b/dom/browser-element/mochitest/mochitest-oop.ini index ff8e7f660769..610b6848c74f 100644 --- a/dom/browser-element/mochitest/mochitest-oop.ini +++ b/dom/browser-element/mochitest/mochitest-oop.ini @@ -44,6 +44,7 @@ skip-if = (toolkit == 'gonk' && !debug) skip-if = (toolkit == 'gonk' && !debug) [test_browserElement_oop_GetScreenshot.html] [test_browserElement_oop_GetScreenshotDppx.html] +skip-if = (toolkit == 'windows') [test_browserElement_oop_Iconchange.html] [test_browserElement_oop_LoadEvents.html] [test_browserElement_oop_Manifestchange.html] diff --git a/dom/browser-element/mochitest/mochitest.ini b/dom/browser-element/mochitest/mochitest.ini index b263bd50f00f..77d566674734 100644 --- a/dom/browser-element/mochitest/mochitest.ini +++ b/dom/browser-element/mochitest/mochitest.ini @@ -162,6 +162,7 @@ skip-if = (toolkit == 'gonk' && !debug) [test_browserElement_inproc_GetScreenshot.html] skip-if = (toolkit == 'android' && processor == 'x86') #x86 only [test_browserElement_inproc_GetScreenshotDppx.html] +skip-if = (toolkit == 'windows') [test_browserElement_inproc_Iconchange.html] [test_browserElement_inproc_LoadEvents.html] [test_browserElement_inproc_Manifestchange.html] diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 7812b20832bc..fd7d6c17d2f1 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -308,12 +308,12 @@ public: nsIntRegion strokePaintNeededRegion; FilterSupport::ComputeSourceNeededRegions( - ctx->CurrentState().filter, mgfx::ThebesIntRect(mPostFilterBounds), + ctx->CurrentState().filter, mPostFilterBounds, sourceGraphicNeededRegion, fillPaintNeededRegion, strokePaintNeededRegion); - mSourceGraphicRect = mgfx::ToIntRect(sourceGraphicNeededRegion.GetBounds()); - mFillPaintRect = mgfx::ToIntRect(fillPaintNeededRegion.GetBounds()); - mStrokePaintRect = mgfx::ToIntRect(strokePaintNeededRegion.GetBounds()); + mSourceGraphicRect = sourceGraphicNeededRegion.GetBounds(); + mFillPaintRect = fillPaintNeededRegion.GetBounds(); + mStrokePaintRect = strokePaintNeededRegion.GetBounds(); mSourceGraphicRect = mSourceGraphicRect.Intersect(aPreFilterBounds); @@ -600,10 +600,10 @@ private: nsIntRegion strokePaintNeededRegion; FilterSupport::ComputeSourceNeededRegions( - ctx->CurrentState().filter, mgfx::ThebesIntRect(mgfx::RoundedToInt(aDestBounds)), + ctx->CurrentState().filter, mgfx::RoundedToInt(aDestBounds), sourceGraphicNeededRegion, fillPaintNeededRegion, strokePaintNeededRegion); - return mgfx::Rect(mgfx::ToIntRect(sourceGraphicNeededRegion.GetBounds())); + return mgfx::Rect(sourceGraphicNeededRegion.GetBounds()); } mgfx::Rect @@ -639,8 +639,8 @@ private: nsIntRegion extents = mgfx::FilterSupport::ComputePostFilterExtents(ctx->CurrentState().filter, - mgfx::ThebesIntRect(intBounds)); - return mgfx::Rect(mgfx::ToIntRect(extents.GetBounds())); + intBounds); + return mgfx::Rect(extents.GetBounds()); } RefPtr mTarget; diff --git a/dom/events/WheelHandlingHelper.h b/dom/events/WheelHandlingHelper.h index 11eb03f62b9e..7cc3b8e08cc9 100644 --- a/dom/events/WheelHandlingHelper.h +++ b/dom/events/WheelHandlingHelper.h @@ -11,12 +11,11 @@ #include "mozilla/EventForwards.h" #include "nsCoord.h" #include "nsIFrame.h" +#include "nsPoint.h" class nsIScrollableFrame; class nsITimer; -struct nsIntPoint; - namespace mozilla { class EventStateManager; diff --git a/dom/events/test/test_clickevent_on_input.html b/dom/events/test/test_clickevent_on_input.html index 21838b48684f..86737329f93c 100644 --- a/dom/events/test/test_clickevent_on_input.html +++ b/dom/events/test/test_clickevent_on_input.html @@ -49,13 +49,26 @@ function isEnabledMiddleClickPaste() } } +function isEnabledTouchCaret() +{ + try { + return SpecialPowers.getBoolPref("touchcaret.enabled"); + } catch (e) { + return false; + } +} + function doTest(aButton) { // NOTE #1: Right click causes a context menu to popup, then, the click event // isn't generated. // NOTE #2: If middle click causes text to be pasted, then, the click event // isn't generated. - if (aButton != 2 && (aButton != 1 || !isEnabledMiddleClickPaste())) { + // NOTE #3: If touch caret is enabled, touch caret would ovelap input element, + // then, the click event isn't generated. + if (aButton != 2 && + (aButton != 1 || !isEnabledMiddleClickPaste()) && + (aButton != 0 || !isEnabledTouchCaret())) { gClickCount = 0; // click on border of input synthesizeMouse(input, 5, 5, { button: aButton }); diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index f10b7a2e94d8..df74b1eea1cf 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -37,9 +37,9 @@ using nscolor from "nsColor.h"; using class mozilla::WidgetCompositionEvent from "ipc/nsGUIEventIPC.h"; using struct mozilla::widget::IMENotification from "nsIWidget.h"; using struct nsIMEUpdatePreference from "nsIWidget.h"; -using struct nsIntPoint from "nsPoint.h"; -using struct nsIntRect from "nsRect.h"; using mozilla::gfx::IntSize from "mozilla/gfx/Point.h"; +using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h"; +using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h"; using class mozilla::WidgetKeyboardEvent from "ipc/nsGUIEventIPC.h"; using class mozilla::WidgetMouseEvent from "ipc/nsGUIEventIPC.h"; using class mozilla::WidgetWheelEvent from "ipc/nsGUIEventIPC.h"; @@ -488,11 +488,11 @@ parent: uint64_t aObserverId); SynthesizeNativeTouchPoint(uint32_t aPointerId, TouchPointerState aPointerState, - nsIntPoint aPointerScreenPoint, + IntPoint aPointerScreenPoint, double aPointerPressure, uint32_t aPointerOrientation, uint64_t aObserverId); - SynthesizeNativeTouchTap(nsIntPoint aPointerScreenPoint, + SynthesizeNativeTouchTap(IntPoint aPointerScreenPoint, bool aLongTap, uint64_t aObserverId); ClearNativeTouchSequence(uint64_t aObserverId); @@ -548,8 +548,8 @@ child: CacheFileDescriptor(nsString path, FileDescriptor fd); - UpdateDimensions(nsIntRect rect, ScreenIntSize size, ScreenOrientation orientation, - nsIntPoint chromeDisp) compress; + UpdateDimensions(IntRect rect, ScreenIntSize size, ScreenOrientation orientation, + LayoutDeviceIntPoint chromeDisp) compress; UpdateFrame(FrameMetrics frame); diff --git a/dom/ipc/PPluginWidget.ipdl b/dom/ipc/PPluginWidget.ipdl index 02b86e9c77cd..174e83cdf275 100644 --- a/dom/ipc/PPluginWidget.ipdl +++ b/dom/ipc/PPluginWidget.ipdl @@ -6,7 +6,7 @@ include protocol PBrowser; include "mozilla/GfxMessageUtils.h"; -using struct nsIntRect from "nsRect.h"; +using nsIntRect from "nsRect.h"; namespace mozilla { namespace plugins { diff --git a/dom/ipc/PScreenManager.ipdl b/dom/ipc/PScreenManager.ipdl index d958993fb0ad..844821c8f443 100644 --- a/dom/ipc/PScreenManager.ipdl +++ b/dom/ipc/PScreenManager.ipdl @@ -8,7 +8,7 @@ include protocol PContent; include "mozilla/GfxMessageUtils.h"; -using struct nsIntRect from "nsRect.h"; +using nsIntRect from "nsRect.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; namespace mozilla { diff --git a/dom/ipc/PreallocatedProcessManager.cpp b/dom/ipc/PreallocatedProcessManager.cpp index 02cd433acc2b..eda2bc5bd508 100644 --- a/dom/ipc/PreallocatedProcessManager.cpp +++ b/dom/ipc/PreallocatedProcessManager.cpp @@ -92,6 +92,47 @@ private: bool mEnabled; bool mShutdown; nsRefPtr mPreallocatedAppProcess; + +#if defined(MOZ_NUWA_PROCESS) && defined(ENABLE_TESTS) + // For testing NS_NewUnmonitoredThread(). + + void CreateUnmonitoredThread(); + void DestroyUnmonitoredThread(); + + class UnmonitoredThreadRunnable : public nsRunnable + { + public: + UnmonitoredThreadRunnable() + : mMonitor("UnmonitoredThreadRunnable") + , mEnabled(true) + { } + + NS_IMETHODIMP Run() override + { + MonitorAutoLock mon(mMonitor); + while (mEnabled) { + mMonitor.Wait(); + } + return NS_OK; + } + + void Disable() + { + MonitorAutoLock mon(mMonitor); + mEnabled = false; + mMonitor.NotifyAll(); + } + + private: + ~UnmonitoredThreadRunnable() { } + + Monitor mMonitor; + bool mEnabled; + }; + + nsCOMPtr mUnmonitoredThread; + nsRefPtr mUnmonitoredThreadRunnable; +#endif }; /* static */ StaticRefPtr @@ -155,6 +196,40 @@ PreallocatedProcessManagerImpl::Observe(nsISupports* aSubject, return NS_OK; } +#if defined(MOZ_NUWA_PROCESS) && defined(ENABLE_TESTS) +void +PreallocatedProcessManagerImpl::CreateUnmonitoredThread() +{ + if (Preferences::GetBool("dom.ipc.newUnmonitoredThread.testMode")) { + // Create an unmonitored thread and dispatch a blocking runnable in test + // case startup. + nsresult rv = NS_NewUnmonitoredThread(getter_AddRefs(mUnmonitoredThread), + nullptr); + NS_ENSURE_SUCCESS_VOID(rv); + + mUnmonitoredThreadRunnable = new UnmonitoredThreadRunnable(); + mUnmonitoredThread->Dispatch(mUnmonitoredThreadRunnable, + NS_DISPATCH_NORMAL); + } +} + +void +PreallocatedProcessManagerImpl::DestroyUnmonitoredThread() +{ + // Cleanup after the test case finishes. + if (mUnmonitoredThreadRunnable) { + mUnmonitoredThreadRunnable->Disable(); + } + + if (mUnmonitoredThread) { + mUnmonitoredThread->Shutdown(); + } + + mUnmonitoredThreadRunnable = nullptr; + mUnmonitoredThread = nullptr; +} +#endif + void PreallocatedProcessManagerImpl::RereadPrefs() { @@ -180,6 +255,11 @@ PreallocatedProcessManagerImpl::Enable() mEnabled = true; #ifdef MOZ_NUWA_PROCESS +#ifdef ENABLE_TESTS + // For testing New_UnmonitoredThread(). + CreateUnmonitoredThread(); +#endif + ScheduleDelayedNuwaFork(); #else AllocateAfterDelay(); @@ -372,6 +452,11 @@ PreallocatedProcessManagerImpl::Disable() mEnabled = false; #ifdef MOZ_NUWA_PROCESS +#ifdef ENABLE_TESTS + // Shut down the test-only unmonitored thread. + DestroyUnmonitoredThread(); +#endif + // Cancel pending fork. if (mPreallocateAppProcessTask) { mPreallocateAppProcessTask->Cancel(); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 1a5692aca412..5bb4f164d9b7 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1085,7 +1085,7 @@ TabChild::Init() } mWidget->Create( nullptr, 0, // no parents - nsIntRect(nsIntPoint(0, 0), nsIntSize(0, 0)), + gfx::IntRect(gfx::IntPoint(0, 0), gfx::IntSize(0, 0)), nullptr // HandleWidgetEvent ); @@ -2018,7 +2018,7 @@ TabChild::RecvShow(const ScreenIntSize& aSize, bool TabChild::RecvUpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size, - const ScreenOrientation& orientation, const nsIntPoint& chromeDisp) + const ScreenOrientation& orientation, const LayoutDeviceIntPoint& chromeDisp) { if (!mRemoteFrame) { return true; @@ -3179,7 +3179,7 @@ TabChild::CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut) initData.mUnicode = false; initData.clipChildren = true; initData.clipSiblings = true; - nsresult rv = pluginWidget->Create(aParent, nullptr, nsIntRect(nsIntPoint(0, 0), + nsresult rv = pluginWidget->Create(aParent, nullptr, gfx::IntRect(gfx::IntPoint(0, 0), nsIntSize(0, 0)), &initData); if (NS_FAILED(rv)) { NS_WARNING("Creating native plugin widget on the chrome side failed."); diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 42face51d904..e9da68c1112b 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -322,7 +322,7 @@ public: virtual bool RecvUpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size, const ScreenOrientation& orientation, - const nsIntPoint& chromeDisp) override; + const LayoutDeviceIntPoint& chromeDisp) override; virtual bool RecvUpdateFrame(const layers::FrameMetrics& aFrameMetrics) override; virtual bool RecvRequestFlingSnap(const ViewID& aScrollId, const CSSPoint& aDestination) override; @@ -487,7 +487,7 @@ public: bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) override; nsresult CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut); - nsIntPoint GetChromeDisplacement() { return mChromeDisp; }; + LayoutDeviceIntPoint GetChromeDisplacement() { return mChromeDisp; }; bool IPCOpen() { return mIPCOpen; } @@ -625,7 +625,7 @@ private: bool mHasValidInnerSize; bool mDestroyed; // Position of tab, relative to parent widget (typically the window) - nsIntPoint mChromeDisp; + LayoutDeviceIntPoint mChromeDisp; TabId mUniqueId; float mDPI; double mDefaultScale; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index a0e65476f787..d927bb2a7462 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -270,7 +270,6 @@ TabParent::TabParent(nsIContentParent* aManager, , mDPI(0) , mDefaultScale(0) , mUpdatedDimensions(false) - , mChromeOffset(0, 0) , mManager(aManager) , mMarkedDestroying(false) , mIsDestroyed(false) @@ -338,16 +337,27 @@ TabParent::SetOwnerElement(Element* aElement) // Update to the new content, and register to listen for events from it. mFrameElement = aElement; - if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) { - nsCOMPtr window = mFrameElement->OwnerDoc()->GetWindow(); - nsCOMPtr eventTarget = window->GetTopWindowRoot(); - if (eventTarget) { - eventTarget->AddEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"), - this, false, false); + + AddWindowListeners(); + TryCacheDPIAndScale(); +} + +void +TabParent::AddWindowListeners() +{ + if (mFrameElement && mFrameElement->OwnerDoc()) { + if (nsCOMPtr window = mFrameElement->OwnerDoc()->GetWindow()) { + nsCOMPtr eventTarget = window->GetTopWindowRoot(); + if (eventTarget) { + eventTarget->AddEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"), + this, false, false); + } + } + if (nsIPresShell* shell = mFrameElement->OwnerDoc()->GetShell()) { + mPresShellWithRefreshListener = shell; + shell->AddPostRefreshObserver(this); } } - - TryCacheDPIAndScale(); } void @@ -361,6 +371,18 @@ TabParent::RemoveWindowListeners() this, false); } } + if (mPresShellWithRefreshListener) { + mPresShellWithRefreshListener->RemovePostRefreshObserver(this); + mPresShellWithRefreshListener = nullptr; + } +} + +void +TabParent::DidRefresh() +{ + if (mChromeOffset != -GetChildProcessOffset()) { + UpdatePosition(); + } } void @@ -395,6 +417,8 @@ TabParent::Destroy() return; } + RemoveWindowListeners(); + // If this fails, it's most likely due to a content-process crash, // and auto-cleanup will kick in. Otherwise, the child side will // destroy itself and send back __delete__(). @@ -904,6 +928,19 @@ TabParent::RecvSetDimensions(const uint32_t& aFlags, return false; } +nsresult +TabParent::UpdatePosition() +{ + nsRefPtr frameLoader = GetFrameLoader(); + if (!frameLoader) { + return NS_OK; + } + nsIntRect windowDims; + NS_ENSURE_SUCCESS(frameLoader->GetWindowDimensions(windowDims), NS_ERROR_FAILURE); + UpdateDimensions(windowDims, mDimensions); + return NS_OK; +} + void TabParent::UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size) { @@ -913,17 +950,18 @@ TabParent::UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size) hal::ScreenConfiguration config; hal::GetCurrentScreenConfiguration(&config); ScreenOrientation orientation = config.orientation(); - nsIntPoint chromeOffset = -LayoutDevicePixel::ToUntyped(GetChildProcessOffset()); + LayoutDeviceIntPoint chromeOffset = -GetChildProcessOffset(); + + nsCOMPtr widget = GetWidget(); + nsIntRect contentRect = rect; + if (widget) { + contentRect.x += widget->GetClientOffset().x; + contentRect.y += widget->GetClientOffset().y; + } if (!mUpdatedDimensions || mOrientation != orientation || - mDimensions != size || !mRect.IsEqualEdges(rect) || + mDimensions != size || !mRect.IsEqualEdges(contentRect) || chromeOffset != mChromeOffset) { - nsCOMPtr widget = GetWidget(); - nsIntRect contentRect = rect; - if (widget) { - contentRect.x += widget->GetClientOffset().x; - contentRect.y += widget->GetClientOffset().y; - } mUpdatedDimensions = true; mRect = contentRect; @@ -2990,14 +3028,7 @@ TabParent::HandleEvent(nsIDOMEvent* aEvent) if (eventType.EqualsLiteral("MozUpdateWindowPos") && !mIsDestroyed) { // This event is sent when the widget moved. Therefore we only update // the position. - nsRefPtr frameLoader = GetFrameLoader(); - if (!frameLoader) { - return NS_OK; - } - nsIntRect windowDims; - NS_ENSURE_SUCCESS(frameLoader->GetWindowDimensions(windowDims), NS_ERROR_FAILURE); - UpdateDimensions(windowDims, mDimensions); - return NS_OK; + return UpdatePosition(); } return NS_OK; } diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index adfc3af59a1e..145738ab53b6 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -23,6 +23,7 @@ #include "nsISecureBrowserUI.h" #include "nsITabParent.h" #include "nsIXULBrowserWindow.h" +#include "nsRefreshDriver.h" #include "nsWeakReference.h" #include "Units.h" #include "nsIWidget.h" @@ -74,6 +75,7 @@ class TabParent final : public PBrowserParent , public nsISecureBrowserUI , public nsSupportsWeakReference , public TabContext + , public nsAPostRefreshObserver { typedef mozilla::dom::ClonedMessageData ClonedMessageData; @@ -119,6 +121,8 @@ public: void Destroy(); void RemoveWindowListeners(); + void AddWindowListeners(); + void DidRefresh() override; virtual bool RecvMoveFocus(const bool& aForward) override; virtual bool RecvEvent(const RemoteDOMEvent& aEvent) override; @@ -479,7 +483,7 @@ protected: float mDPI; CSSToLayoutDeviceScale mDefaultScale; bool mUpdatedDimensions; - nsIntPoint mChromeOffset; + LayoutDeviceIntPoint mChromeOffset; private: already_AddRefed GetFrameLoader(bool aUseCachedFrameLoaderAfterDestroy = false) const; @@ -487,6 +491,8 @@ private: nsRefPtr mManager; void TryCacheDPIAndScale(); + nsresult UpdatePosition(); + CSSPoint AdjustTapToChildWidget(const CSSPoint& aPoint); // Update state prior to routing an APZ-aware event to the child process. @@ -595,6 +601,8 @@ private: // cursor. This happens whenever the cursor is in the tab's region. bool mTabSetsCursor; + nsRefPtr mPresShellWithRefreshListener; + private: // This is used when APZ needs to find the TabParent associated with a layer // to dispatch events. diff --git a/dom/ipc/tests/mochitest.ini b/dom/ipc/tests/mochitest.ini index 52780cc5dcfb..067e24279a76 100644 --- a/dom/ipc/tests/mochitest.ini +++ b/dom/ipc/tests/mochitest.ini @@ -17,6 +17,8 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet' skip-if = toolkit != 'gonk' [test_NuwaProcessDeadlock.html] skip-if = toolkit != 'gonk' +[test_NewUnmonitoredThread.html] +skip-if = toolkit != 'gonk' [test_child_docshell.html] skip-if = toolkit == 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf [test_CrashService_crash.html] diff --git a/dom/ipc/tests/test_NewUnmonitoredThread.html b/dom/ipc/tests/test_NewUnmonitoredThread.html new file mode 100644 index 000000000000..c52a45a3fcea --- /dev/null +++ b/dom/ipc/tests/test_NewUnmonitoredThread.html @@ -0,0 +1,80 @@ + + + + + + + + + + + + diff --git a/dom/media/VideoUtils.h b/dom/media/VideoUtils.h index 6bc06c1a463e..495e1ae6bfa4 100644 --- a/dom/media/VideoUtils.h +++ b/dom/media/VideoUtils.h @@ -12,6 +12,7 @@ #include "mozilla/CheckedInt.h" #include "nsIThread.h" #include "nsSize.h" +#include "nsRect.h" #if !(defined(XP_WIN) || defined(XP_MACOSX) || defined(LINUX)) || \ defined(MOZ_ASAN) @@ -28,8 +29,6 @@ using mozilla::CheckedUint64; using mozilla::CheckedInt32; using mozilla::CheckedUint32; -struct nsIntRect; - // This file contains stuff we'd rather put elsewhere, but which is // dependent on other changes which we don't want to wait for. We plan to // remove this file in the near future. diff --git a/dom/media/android/AndroidMediaReader.cpp b/dom/media/android/AndroidMediaReader.cpp index 6ba4d9e7b6b1..51cf9214c617 100644 --- a/dom/media/android/AndroidMediaReader.cpp +++ b/dom/media/android/AndroidMediaReader.cpp @@ -174,7 +174,7 @@ bool AndroidMediaReader::DecodeVideoFrame(bool &aKeyframeSkip, currentImage = bufferCallback.GetImage(); int64_t pos = mDecoder->GetResource()->Tell(); - IntRect picture = ToIntRect(mPicture); + IntRect picture = mPicture; nsRefPtr v; if (currentImage) { diff --git a/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp b/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp index c9f2369c4e4d..6a44f33b6155 100644 --- a/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp +++ b/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp @@ -198,7 +198,7 @@ GonkVideoDecoderManager::CreateVideoData(int64_t aStreamOffset, VideoData **v) keyFrame = 0; } - gfx::IntRect picture = ToIntRect(mPicture); + gfx::IntRect picture = mPicture; if (mFrameInfo.mWidth != mInitialFrame.width || mFrameInfo.mHeight != mInitialFrame.height) { diff --git a/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp b/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp index e1b686e71d81..a55dc1605280 100644 --- a/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp +++ b/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp @@ -28,7 +28,6 @@ PRLogModuleInfo* GetDemuxerLog(); #define LOG(...) #endif -using mozilla::gfx::ToIntRect; using mozilla::layers::Image; using mozilla::layers::IMFYCbCrImage; using mozilla::layers::LayerManager; @@ -404,7 +403,7 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample, VideoData::SetVideoDataToImage(image, mVideoInfo, b, - ToIntRect(mPictureRegion), + mPictureRegion, false); nsRefPtr v = @@ -416,7 +415,7 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample, image.forget(), false, -1, - ToIntRect(mPictureRegion)); + mPictureRegion); v.forget(aOutVideoData); return S_OK; @@ -453,7 +452,7 @@ WMFVideoMFTManager::CreateD3DVideoFrame(IMFSample* aSample, image.forget(), false, -1, - ToIntRect(mPictureRegion)); + mPictureRegion); NS_ENSURE_TRUE(v, E_FAIL); v.forget(aOutVideoData); diff --git a/dom/media/ogg/OggReader.cpp b/dom/media/ogg/OggReader.cpp index e77d76447755..387ae432ae69 100644 --- a/dom/media/ogg/OggReader.cpp +++ b/dom/media/ogg/OggReader.cpp @@ -890,7 +890,7 @@ nsresult OggReader::DecodeTheora(ogg_packet* aPacket, int64_t aTimeThreshold) b, isKeyframe, aPacket->granulepos, - ToIntRect(mPicture)); + mPicture); if (!v) { // There may be other reasons for this error, but for // simplicity just assume the worst case: out of memory. diff --git a/dom/media/omx/MediaCodecReader.cpp b/dom/media/omx/MediaCodecReader.cpp index cddccbea1486..50f872c486a0 100644 --- a/dom/media/omx/MediaCodecReader.cpp +++ b/dom/media/omx/MediaCodecReader.cpp @@ -1645,7 +1645,7 @@ MediaCodecReader::UpdateVideoInfo() } // Relative picture size - gfx::IntRect relative_picture_rect = gfx::ToIntRect(picture_rect); + gfx::IntRect relative_picture_rect = picture_rect; if (mVideoTrack.mWidth != mVideoTrack.mFrameSize.width || mVideoTrack.mHeight != mVideoTrack.mFrameSize.height) { // Frame size is different from what the container reports. This is legal, diff --git a/dom/media/omx/MediaOmxReader.cpp b/dom/media/omx/MediaOmxReader.cpp index 7043838b060c..8241074e52e3 100644 --- a/dom/media/omx/MediaOmxReader.cpp +++ b/dom/media/omx/MediaOmxReader.cpp @@ -403,7 +403,7 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip, aKeyframeSkip = false; - IntRect picture = ToIntRect(mPicture); + IntRect picture = mPicture; if (frame.Y.mWidth != mInitialFrame.width || frame.Y.mHeight != mInitialFrame.height) { diff --git a/dom/media/raw/RawReader.cpp b/dom/media/raw/RawReader.cpp index 7c65e6e1daef..6362bb0b48e3 100644 --- a/dom/media/raw/RawReader.cpp +++ b/dom/media/raw/RawReader.cpp @@ -218,7 +218,7 @@ bool RawReader::DecodeVideoFrame(bool &aKeyframeSkip, b, 1, // In raw video every frame is a keyframe -1, - ToIntRect(mPicture)); + mPicture); if (!v) return false; diff --git a/dom/media/webm/SoftwareWebMVideoDecoder.cpp b/dom/media/webm/SoftwareWebMVideoDecoder.cpp index b2a9b617a914..377c70d5a49a 100644 --- a/dom/media/webm/SoftwareWebMVideoDecoder.cpp +++ b/dom/media/webm/SoftwareWebMVideoDecoder.cpp @@ -190,7 +190,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip, b.mPlanes[2].mOffset = b.mPlanes[2].mSkip = 0; nsIntRect pictureRect = mReader->GetPicture(); - IntRect picture = ToIntRect(pictureRect); + IntRect picture = pictureRect; nsIntSize initFrame = mReader->GetInitialFrame(); if (img->d_w != static_cast(initFrame.width) || img->d_h != static_cast(initFrame.height)) { diff --git a/dom/media/wmf/DXVA2Manager.h b/dom/media/wmf/DXVA2Manager.h index d0fe3002f8ae..5770e4d3386b 100644 --- a/dom/media/wmf/DXVA2Manager.h +++ b/dom/media/wmf/DXVA2Manager.h @@ -9,8 +9,7 @@ #include "WMF.h" #include "nsAutoPtr.h" #include "mozilla/Mutex.h" - -struct nsIntRect; +#include "nsRect.h" namespace mozilla { diff --git a/dom/media/wmf/WMFReader.cpp b/dom/media/wmf/WMFReader.cpp index 03a94a4c5e18..cbc1af7ad2da 100644 --- a/dom/media/wmf/WMFReader.cpp +++ b/dom/media/wmf/WMFReader.cpp @@ -747,7 +747,7 @@ WMFReader::CreateBasicVideoFrame(IMFSample* aSample, b, false, -1, - ToIntRect(mPictureRegion)); + mPictureRegion); if (twoDBuffer) { twoDBuffer->Unlock2D(); } else { @@ -789,7 +789,7 @@ WMFReader::CreateD3DVideoFrame(IMFSample* aSample, image.forget(), false, -1, - ToIntRect(mPictureRegion)); + mPictureRegion); NS_ENSURE_TRUE(v, E_FAIL); v.forget(aOutVideoData); diff --git a/dom/mobilemessage/gonk/MmsService.js b/dom/mobilemessage/gonk/MmsService.js index 1c1d409e25b2..9b68559efa6e 100644 --- a/dom/mobilemessage/gonk/MmsService.js +++ b/dom/mobilemessage/gonk/MmsService.js @@ -167,6 +167,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService", "@mozilla.org/mobileconnection/mobileconnectionservice;1", "nsIMobileConnectionService"); +XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", + "@mozilla.org/network/service;1", + "nsINetworkService"); + XPCOMUtils.defineLazyGetter(this, "MMS", function() { let MMS = {}; Cu.import("resource://gre/modules/MmsPduHelper.jsm", MMS); @@ -706,33 +710,38 @@ XPCOMUtils.defineLazyGetter(this, "gMmsTransactionHelper", function() { url = mmsConnection.mmsc; } - let startTransaction = () => { + let startTransaction = netId => { if (DEBUG) debug("sendRequest: register proxy filter to " + url); let proxyFilter = new MmsProxyFilter(mmsConnection, url); gpps.registerFilter(proxyFilter, 0); cancellable.xhr = this.sendHttpRequest(mmsConnection, method, - url, istream, proxyFilter, + url, istream, proxyFilter, netId, (aHttpStatus, aData) => cancellable.done(aHttpStatus, aData)); }; - mmsConnection.ensureRouting(url) - .then(() => startTransaction(), - (aError) => { - debug("Failed to ensureRouting: " + aError); + let onRejected = aReason => { + debug(aReason); + mmsConnection.release(); + cancellable.done(_HTTP_STATUS_FAILED_TO_ROUTE, null); + }; - mmsConnection.release(); - cancellable.done(_HTTP_STATUS_FAILED_TO_ROUTE, null); - }); + // TODO: |getNetId| will be implemented as a sync call in nsINetworkManager + // once Bug 1141903 is landed. + mmsConnection.ensureRouting(url) + .then(() => gNetworkService.getNetId(mmsConnection.networkInterface.name), + (aReason) => onRejected('Failed to ensureRouting: ' + aReason)) + .then((netId) => startTransaction(netId), + (aReason) => onRejected('Failed to getNetId: ' + aReason)); }); return cancellable; }, sendHttpRequest: function(mmsConnection, method, url, istream, proxyFilter, - callback) { + netId, callback) { let releaseMmsConnectionAndCallback = (httpStatus, data) => { gpps.unregisterFilter(proxyFilter); // Always release the MMS network connection before callback. @@ -745,6 +754,7 @@ XPCOMUtils.defineLazyGetter(this, "gMmsTransactionHelper", function() { .createInstance(Ci.nsIXMLHttpRequest); // Basic setups + xhr.networkInterfaceId = netId; xhr.open(method, url, true); xhr.responseType = "arraybuffer"; if (istream) { diff --git a/dom/nfc/gonk/Nfc.js b/dom/nfc/gonk/Nfc.js index c7553b90433e..bdb472e2f40a 100644 --- a/dom/nfc/gonk/Nfc.js +++ b/dom/nfc/gonk/Nfc.js @@ -613,6 +613,10 @@ Nfc.prototype = { message.target.sendAsyncMessage(nfcMsgType, message.data); }, + getErrorMessage: function getErrorMessage(errorCode) { + return NFC.NFC_ERROR_MSG[errorCode]; + }, + /** * Process the incoming message from the NFC Service. */ diff --git a/dom/nfc/gonk/NfcService.h b/dom/nfc/gonk/NfcService.h index 56e2150f2498..ef9404cf8aa0 100644 --- a/dom/nfc/gonk/NfcService.h +++ b/dom/nfc/gonk/NfcService.h @@ -6,7 +6,7 @@ #define NfcService_h #include "mozilla/ipc/Nfc.h" -#include "mozilla/ipc/UnixSocket.h" +#include "mozilla/ipc/SocketBase.h" #include "nsCOMPtr.h" #include "nsINfcService.h" #include "NfcMessageHandler.h" diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index 5b5d97e0f842..2101d3900998 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -24,7 +24,6 @@ #endif class nsIInputStream; -struct nsIntRect; class nsPluginDOMContextMenuListener; class nsPluginFrame; class nsDisplayListBuilder; diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index 659805e99981..cd608eca2033 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -26,7 +26,7 @@ using gfxIntSize from "nsSize.h"; using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; using mozilla::plugins::WindowsSharedMemoryHandle from "mozilla/plugins/PluginMessageUtils.h"; using mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h"; -using struct nsIntRect from "nsRect.h"; +using nsIntRect from "nsRect.h"; namespace mozilla { namespace plugins { diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 967294af1c30..4425fbc86c40 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -3087,7 +3087,7 @@ PluginInstanceChild::PaintRectToSurface(const nsIntRect& aRect, RefPtr dt = CreateDrawTargetForSurface(aSurface); RefPtr surface = gfxPlatform::GetSourceSurfaceForSurface(dt, renderSurface); - dt->CopySurface(surface, ToIntRect(aRect), ToIntPoint(aRect.TopLeft())); + dt->CopySurface(surface, aRect, aRect.TopLeft()); } } @@ -3145,7 +3145,7 @@ PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect, RefPtr dt = CreateDrawTargetForSurface(whiteImage); RefPtr surface = gfxPlatform::GetSourceSurfaceForSurface(dt, aSurface); - dt->CopySurface(surface, ToIntRect(rect), IntPoint()); + dt->CopySurface(surface, rect, IntPoint()); } // Paint the plugin directly onto the target, with a black @@ -3191,7 +3191,7 @@ PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect, gfxPlatform::GetSourceSurfaceForSurface(dt, blackImage); dt->CopySurface(surface, IntRect(0, 0, rect.width, rect.height), - ToIntPoint(rect.TopLeft())); + rect.TopLeft()); } } @@ -3328,9 +3328,7 @@ PluginInstanceChild::ShowPluginFrame() RefPtr dt = CreateDrawTargetForSurface(surface); RefPtr backgroundSurface = gfxPlatform::GetSourceSurfaceForSurface(dt, mBackground); - dt->CopySurface(backgroundSurface, - ToIntRect(rect), - ToIntPoint(rect.TopLeft())); + dt->CopySurface(backgroundSurface, rect, rect.TopLeft()); } // ... and hand off to the plugin // BEWARE: mBackground may die during this call @@ -3463,7 +3461,7 @@ PluginInstanceChild::ReadbackDifferenceRect(const nsIntRect& rect) nsIntRegionRectIterator iter(result); const nsIntRect* r; while ((r = iter.Next()) != nullptr) { - dt->CopySurface(source, ToIntRect(*r), ToIntPoint(r->TopLeft())); + dt->CopySurface(source, *r, r->TopLeft()); } return true; diff --git a/dom/plugins/ipc/PluginLibrary.h b/dom/plugins/ipc/PluginLibrary.h index 275afa439307..efec7ce84ca1 100644 --- a/dom/plugins/ipc/PluginLibrary.h +++ b/dom/plugins/ipc/PluginLibrary.h @@ -15,10 +15,10 @@ #include "nsError.h" #include "mozilla/EventForwards.h" #include "nsSize.h" +#include "nsRect.h" class gfxContext; class nsCString; -struct nsIntRect; class nsNPAPIPlugin; namespace mozilla { diff --git a/dom/plugins/ipc/PluginUtilsOSX.h b/dom/plugins/ipc/PluginUtilsOSX.h index 164efe814db4..7abab1efdbf9 100644 --- a/dom/plugins/ipc/PluginUtilsOSX.h +++ b/dom/plugins/ipc/PluginUtilsOSX.h @@ -9,8 +9,7 @@ #include "npapi.h" #include "mozilla/gfx/QuartzSupport.h" - -struct nsIntRect; +#include "nsRect.h" namespace mozilla { namespace plugins { diff --git a/dom/system/gonk/AutoMounter.cpp b/dom/system/gonk/AutoMounter.cpp index 2c5450f2fae8..6f1a4c6df98f 100644 --- a/dom/system/gonk/AutoMounter.cpp +++ b/dom/system/gonk/AutoMounter.cpp @@ -38,6 +38,7 @@ #include "OpenFileFinder.h" #include "Volume.h" #include "VolumeManager.h" +#include "nsIStatusReporter.h" using namespace mozilla::hal; USING_MTP_NAMESPACE @@ -259,6 +260,10 @@ public: } void UpdateState(); + void GetStatus(bool& umsAvail, bool& umsConfigured, bool& umsEnabled, bool& mtpAvail, + bool& mtpConfigured, bool& mtpEnabled, bool& rndisConfigured); + + nsresult Dump(nsACString& desc); void ConfigureUsbFunction(const char* aUsbFunc); @@ -459,6 +464,21 @@ private: static StaticRefPtr sAutoMounter; static StaticRefPtr sMozMtpServer; +// The following is for status reporter +enum STATE_REPORTER_STATE +{ + REPORTER_UNREGISTERED, + REPORTER_REGISTERED +}; + +static int status_reporter_progress = REPORTER_UNREGISTERED; +nsresult getState(nsACString &desc) +{ + sAutoMounter->Dump(desc); + return NS_OK; +} +NS_STATUS_REPORTER_IMPLEMENT(AutoMounter, "AutoMounter", getState); + /***************************************************************************/ void @@ -703,56 +723,12 @@ AutoMounter::UpdateState() // // Since IsUsbCablePluggedIn returns state == CONFIGURED, it will look // like a cable pull and replugin. - - bool umsAvail = false; - bool umsConfigured = false; - bool umsEnabled = false; - bool mtpAvail = false; - bool mtpConfigured = false; - bool mtpEnabled = false; - bool rndisConfigured = false; + bool umsAvail, umsConfigured, umsEnabled; + bool mtpAvail, mtpConfigured, mtpEnabled; + bool rndisConfigured; bool usbCablePluggedIn = IsUsbCablePluggedIn(); - - if (access(ICS_SYS_USB_FUNCTIONS, F_OK) == 0) { - char functionsStr[60]; - if (!ReadSysFile(ICS_SYS_USB_FUNCTIONS, functionsStr, sizeof(functionsStr))) { - ERR("Error reading file '%s': %s", ICS_SYS_USB_FUNCTIONS, strerror(errno)); - functionsStr[0] = '\0'; - } - DBG("UpdateState: USB functions: '%s'", functionsStr); - - bool usbConfigured = IsUsbConfigured(); - - // On the Nexus 4/5, it advertises that the UMS usb function is available, - // but we have a further requirement that mass_storage be in the - // persist.sys.usb.config property. - char persistSysUsbConfig[PROPERTY_VALUE_MAX]; - property_get(PERSIST_SYS_USB_CONFIG, persistSysUsbConfig, ""); - if (IsUsbFunctionEnabled(persistSysUsbConfig, USB_FUNC_UMS)) { - umsAvail = (access(ICS_SYS_UMS_DIRECTORY, F_OK) == 0); - } - if (umsAvail) { - umsConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_UMS) != nullptr; - umsEnabled = (mMode == AUTOMOUNTER_ENABLE_UMS) || - ((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && umsConfigured); - } else { - umsConfigured = false; - umsEnabled = false; - } - - mtpAvail = (access(ICS_SYS_MTP_DIRECTORY, F_OK) == 0); - if (mtpAvail) { - mtpConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_MTP) != nullptr; - mtpEnabled = (mMode == AUTOMOUNTER_ENABLE_MTP) || - ((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && mtpConfigured); - } else { - mtpConfigured = false; - mtpEnabled = false; - } - - rndisConfigured = strstr(functionsStr, USB_FUNC_RNDIS) != nullptr; - } - + GetStatus(umsAvail, umsConfigured, umsEnabled, mtpAvail, + mtpConfigured, mtpEnabled, rndisConfigured); bool enabled = mtpEnabled || umsEnabled; if (mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) { @@ -1139,6 +1115,167 @@ AutoMounter::UpdateState() /***************************************************************************/ +void AutoMounter::GetStatus(bool& umsAvail, bool& umsConfigured, bool& umsEnabled, + bool& mtpAvail, bool& mtpConfigured, bool& mtpEnabled, + bool& rndisConfigured) +{ + umsConfigured = false; + umsEnabled = false; + mtpAvail = false; + mtpConfigured = false; + mtpEnabled = false; + rndisConfigured = false; + + if (access(ICS_SYS_USB_FUNCTIONS, F_OK) != 0) { + return; + } + + char functionsStr[60]; + if (!ReadSysFile(ICS_SYS_USB_FUNCTIONS, functionsStr, sizeof(functionsStr))) { + ERR("Error reading file '%s': %s", ICS_SYS_USB_FUNCTIONS, strerror(errno)); + functionsStr[0] = '\0'; + } + DBG("GetStatus: USB functions: '%s'", functionsStr); + + bool usbConfigured = IsUsbConfigured(); + + // On the Nexus 4/5, it advertises that the UMS usb function is available, + // but we have a further requirement that mass_storage be in the + // persist.sys.usb.config property. + char persistSysUsbConfig[PROPERTY_VALUE_MAX]; + property_get(PERSIST_SYS_USB_CONFIG, persistSysUsbConfig, ""); + if (IsUsbFunctionEnabled(persistSysUsbConfig, USB_FUNC_UMS)) { + umsAvail = (access(ICS_SYS_UMS_DIRECTORY, F_OK) == 0); + } + if (umsAvail) { + umsConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_UMS) != nullptr; + umsEnabled = (mMode == AUTOMOUNTER_ENABLE_UMS) || + ((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && umsConfigured); + } else { + umsConfigured = false; + umsEnabled = false; + } + + mtpAvail = (access(ICS_SYS_MTP_DIRECTORY, F_OK) == 0); + if (mtpAvail) { + mtpConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_MTP) != nullptr; + mtpEnabled = (mMode == AUTOMOUNTER_ENABLE_MTP) || + ((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && mtpConfigured); + } else { + mtpConfigured = false; + mtpEnabled = false; + } + + rndisConfigured = strstr(functionsStr, USB_FUNC_RNDIS) != nullptr; +} + + +nsresult AutoMounter::Dump(nsACString& desc) +{ + DBG("GetState!"); + bool umsAvail, umsConfigured, umsEnabled; + bool mtpAvail, mtpConfigured, mtpEnabled; + bool rndisConfigured; + GetStatus(umsAvail, umsConfigured, umsEnabled, mtpAvail, + mtpConfigured, mtpEnabled, rndisConfigured); + if (mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) { + // DISABLE_WHEN_UNPLUGGED implies already enabled. + if (!IsUsbCablePluggedIn()) { + mMode = AUTOMOUNTER_DISABLE; + mtpEnabled = false; + umsEnabled = false; + } + } + + // Automounter information + desc += "Current Mode:"; + desc += ModeStr(mMode); + desc += "|"; + + + desc += "Current State:"; + desc += StateStr(mState); + desc += "|"; + + desc += "UMS Status:"; + if (umsAvail) { + desc += "Available"; + } else { + desc += "UnAvailable"; + } + desc += ","; + if (umsConfigured) { + desc += "Configured"; + } else { + desc += "Un-Configured"; + } + desc += ","; + if (umsEnabled) { + desc += "Enabled"; + } else { + desc += "Disabled"; + } + desc += "|"; + + + desc += "MTP Status:"; + if (mtpAvail) { + desc += "Available"; + } else { + desc += "UnAvailable"; + } + desc += ","; + if (mtpConfigured) { + desc += "Configured"; + } else { + desc += "Un-Configured"; + } + desc += ","; + if (mtpEnabled) { + desc += "Enabled"; + } else { + desc += "Disabled"; + } + + + // Volume information + VolumeArray::index_type volIndex; + VolumeArray::size_type numVolumes = VolumeManager::NumVolumes(); + for (volIndex = 0; volIndex < numVolumes; volIndex++) { + RefPtr vol = VolumeManager::GetVolume(volIndex); + + desc += "|"; + desc += vol->NameStr(); + desc += ":"; + desc += vol->StateStr(); + desc += "@"; + desc += vol->MountPoint().get(); + + if (!vol->MediaPresent()) { + continue; + } + + if (vol->CanBeShared()) { + desc += ",CanBeShared"; + } + if (vol->CanBeFormatted()) { + desc += ",CanBeFormatted"; + } + if (vol->CanBeMounted()) { + desc += ",CanBeMounted"; + } + if (vol->IsRemovable()) { + desc += ",Removable"; + } + if (vol->IsHotSwappable()) { + desc += ",HotSwappable"; + } + } + + return NS_OK; +} + + static void InitAutoMounterIOThread() { @@ -1270,6 +1407,12 @@ InitAutoMounter() // start it here and have it send events to the AutoMounter running // on the IO Thread. sUsbCableObserver = new UsbCableObserver(); + + // Register status reporter into reporter manager + if(status_reporter_progress == REPORTER_UNREGISTERED) { + NS_RegisterStatusReporter(new NS_STATUS_REPORTER_NAME(AutoMounter)); + } + status_reporter_progress = REPORTER_REGISTERED; } int32_t @@ -1340,6 +1483,11 @@ ShutdownAutoMounter() if (sAutoMounter) { DBG("ShutdownAutoMounter: About to StopMtpServer"); sAutoMounter->StopMtpServer(); + // Unregister status reporter into reporter manager + if(status_reporter_progress == REPORTER_REGISTERED) { + NS_UnregisterStatusReporter(new NS_STATUS_REPORTER_NAME(AutoMounter)); + } + status_reporter_progress = REPORTER_UNREGISTERED; } sAutoMounterSetting = nullptr; sUsbCableObserver = nullptr; diff --git a/dom/system/gonk/NetworkManager.js b/dom/system/gonk/NetworkManager.js index 5a29545577d1..d7bee41c1015 100644 --- a/dom/system/gonk/NetworkManager.js +++ b/dom/system/gonk/NetworkManager.js @@ -277,48 +277,53 @@ NetworkManager.prototype = { switch (network.state) { case Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED: gNetworkService.createNetwork(network.name, () => { - // Add host route for data calls - if (this.isNetworkTypeMobile(network.type)) { - let currentInterfaceLinks = this.networkInterfaceLinks[networkId]; - let newLinkRoutes = network.getDnses().concat(network.httpProxyHost); - // If gateways have changed, remove all old routes first. - this._handleGateways(networkId, network.getGateways()) - .then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes, - newLinkRoutes, - network.getGateways(), network.name)) - .then(() => currentInterfaceLinks.setLinks(newLinkRoutes, - network.getGateways(), - network.name)); - } // Remove pre-created default route and let setAndConfigureActive() // to set default route only on preferred network gNetworkService.removeDefaultRoute(network); - // Dun type is a special case where we add the default route to a - // secondary table. - if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) { - this.setSecondaryDefaultRoute(network); - } - - this._addSubnetRoutes(network); - this.setAndConfigureActive(); - - // Update data connection when Wifi connected/disconnected - if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) { - for (let i = 0; i < this.mRil.numRadioInterfaces; i++) { - this.mRil.getRadioInterface(i).updateRILNetworkInterface(); + // Set DNS server as early as possible to prevent from + // premature domain name lookup. + gNetworkService.setDNS(network, () => { + // Add host route for data calls + if (this.isNetworkTypeMobile(network.type)) { + let currentInterfaceLinks = this.networkInterfaceLinks[networkId]; + let newLinkRoutes = network.getDnses().concat(network.httpProxyHost); + // If gateways have changed, remove all old routes first. + this._handleGateways(networkId, network.getGateways()) + .then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes, + newLinkRoutes, + network.getGateways(), network.name)) + .then(() => currentInterfaceLinks.setLinks(newLinkRoutes, + network.getGateways(), + network.name)); } - } - // Probing the public network accessibility after routing table is ready - CaptivePortalDetectionHelper - .notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active); + // Dun type is a special case where we add the default route to a + // secondary table. + if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) { + this.setSecondaryDefaultRoute(network); + } - // Notify outer modules like MmsService to start the transaction after - // the configuration of the network interface is done. - Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED, - this.convertConnectionType(network)); + this._addSubnetRoutes(network); + this.setAndConfigureActive(); + + // Update data connection when Wifi connected/disconnected + if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) { + for (let i = 0; i < this.mRil.numRadioInterfaces; i++) { + this.mRil.getRadioInterface(i).updateRILNetworkInterface(); + } + } + + // Probing the public network accessibility after routing table is ready + CaptivePortalDetectionHelper + .notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active); + + // Notify outer modules like MmsService to start the transaction after + // the configuration of the network interface is done. + Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED, + this.convertConnectionType(network)); + }); }); break; @@ -641,7 +646,7 @@ NetworkManager.prototype = { // The override was just set, so reconfigure the network. if (this.active != this._overriddenActive) { this.active = this._overriddenActive; - this._setDefaultRouteAndDNS(this.active, oldActive); + this._setDefaultRouteAndProxy(this.active, oldActive); Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null); } return; @@ -652,7 +657,7 @@ NetworkManager.prototype = { this.active.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED && this.active.type == this._preferredNetworkType) { debug("Active network is already our preferred type."); - this._setDefaultRouteAndDNS(this.active, oldActive); + this._setDefaultRouteAndProxy(this.active, oldActive); return; } @@ -686,10 +691,8 @@ NetworkManager.prototype = { this.active = defaultDataNetwork; } // Don't set default route on secondary APN - if (this.isNetworkTypeSecondaryMobile(this.active.type)) { - gNetworkService.setDNS(this.active, function() {}); - } else { - this._setDefaultRouteAndDNS(this.active, oldActive); + if (!this.isNetworkTypeSecondaryMobile(this.active.type)) { + this._setDefaultRouteAndProxy(this.active, oldActive); } } @@ -713,44 +716,48 @@ NetworkManager.prototype = { return Promise.resolve([hostname]); } - let deferred = Promise.defer(); - let onLookupComplete = (aRequest, aRecord, aStatus) => { - if (!Components.isSuccessCode(aStatus)) { - deferred.reject(new Error( - "Failed to resolve '" + hostname + "', with status: " + aStatus)); - return; - } + // Wrap gDNSService.asyncResolveExtended to a promise, which + // resolves with an array of ip addresses or rejects with + // the reason otherwise. + let hostResolveWrapper = aNetId => { + return new Promise((aResolve, aReject) => { + // Callback for gDNSService.asyncResolveExtended. + let onLookupComplete = (aRequest, aRecord, aStatus) => { + if (!Components.isSuccessCode(aStatus)) { + aReject(new Error("Failed to resolve '" + hostname + + "', with status: " + aStatus)); + return; + } - let retval = []; - while (aRecord.hasMore()) { - retval.push(aRecord.getNextAddrAsString()); - } + let retval = []; + while (aRecord.hasMore()) { + retval.push(aRecord.getNextAddrAsString()); + } - if (!retval.length) { - deferred.reject(new Error("No valid address after DNS lookup!")); - return; - } + if (!retval.length) { + aReject(new Error("No valid address after DNS lookup!")); + return; + } - debug("hostname is resolved: " + hostname); - debug("Addresses: " + JSON.stringify(retval)); + debug("hostname is resolved: " + hostname); + debug("Addresses: " + JSON.stringify(retval)); - deferred.resolve(retval); + aResolve(retval); + }; + + debug('Calling gDNSService.asyncResolveExtended: ' + aNetId + ', ' + hostname); + gDNSService.asyncResolveExtended(hostname, + 0, + aNetId, + onLookupComplete, + Services.tm.mainThread); + }); }; - // Bug 1058282 - Explicitly request ipv4 to get around 8.8.8.8 probe at - // http://androidxref.com/4.3_r2.1/xref/bionic/libc/netbsd/net/getaddrinfo.c#1923 - // - // Whenever MMS connection is the only network interface, there is no - // default route so that any ip probe will fail. - let flags = 0; - if (network.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS) { - flags |= Ci.nsIDNSService.RESOLVE_DISABLE_IPV6; - } - - // TODO: Bug 992772 - Resolve the hostname with specified networkInterface. - gDNSService.asyncResolve(hostname, flags, onLookupComplete, Services.tm.mainThread); - - return deferred.promise; + // TODO: |getNetId| will be implemented as a sync call in nsINetworkManager + // once Bug 1141903 is landed. + return gNetworkService.getNetId(network.name) + .then(aNetId => hostResolveWrapper(aNetId)); }, convertConnectionType: function(network) { @@ -774,15 +781,13 @@ NetworkManager.prototype = { } }, - _setDefaultRouteAndDNS: function(network, oldInterface) { + _setDefaultRouteAndProxy: function(network, oldInterface) { gNetworkService.setDefaultRoute(network, oldInterface, function(success) { if (!success) { gNetworkService.destroyNetwork(network, function() {}); return; } - gNetworkService.setDNS(network, function(result) { - gNetworkService.setNetworkProxy(network); - }); + gNetworkService.setNetworkProxy(network); }); }, }; diff --git a/dom/system/gonk/NetworkService.js b/dom/system/gonk/NetworkService.js index 2421c7dc3320..bf7277cee9d3 100644 --- a/dom/system/gonk/NetworkService.js +++ b/dom/system/gonk/NetworkService.js @@ -391,7 +391,8 @@ NetworkService.prototype = { cmd: "setDNS", ifname: networkInterface.name, domain: "mozilla." + networkInterface.name + ".doman", - dnses: dnses + dnses: dnses, + gateways: networkInterface.getGateways() }; this.controlMessage(options, function(result) { callback.setDnsResult(result.success ? null : result.reason); @@ -762,6 +763,23 @@ NetworkService.prototype = { callback.nativeCommandResult(!result.error); }); }, + + getNetId: function(interfaceName) { + let params = { + cmd: "getNetId", + ifname: interfaceName + }; + + return new Promise((aResolve, aReject) => { + this.controlMessage(params, result => { + if (result.error) { + aReject(result.reason); + return; + } + aResolve(result.netId); + }); + }); + }, }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkService]); diff --git a/dom/system/gonk/NetworkUtils.cpp b/dom/system/gonk/NetworkUtils.cpp index 4735ace510eb..3e3babe28876 100644 --- a/dom/system/gonk/NetworkUtils.cpp +++ b/dom/system/gonk/NetworkUtils.cpp @@ -440,7 +440,6 @@ CommandResult::CommandResult(int32_t aResultCode) strerror_r(abs(aResultCode), strerrorBuf, STRERROR_R_BUF_SIZE); mResult.mReason = NS_ConvertUTF8toUTF16(strerrorBuf); } - mResult.mRet = true; } CommandResult::CommandResult(const mozilla::dom::NetworkResultOptions& aResult) @@ -1535,6 +1534,7 @@ void NetworkUtils::ExecuteCommand(NetworkParams aOptions) BUILD_ENTRY(resetConnections), BUILD_ENTRY(createNetwork), BUILD_ENTRY(destroyNetwork), + BUILD_ENTRY(getNetId), #undef BUILD_ENTRY }; @@ -1704,6 +1704,7 @@ CommandResult NetworkUtils::setDNS(NetworkParams& aOptions) // Lollipop. static CommandFunc COMMAND_CHAIN[] = { setInterfaceDns, + addDefaultRouteToNetwork, defaultAsyncSuccessHandler }; NetIdManager::NetIdInfo netIdInfo; @@ -1717,7 +1718,12 @@ CommandResult NetworkUtils::setDNS(NetworkParams& aOptions) if (SDK_VERSION >= 18) { // JB, KK. static CommandFunc COMMAND_CHAIN[] = { + #if ANDROID_VERSION == 18 + // Since we don't use per-interface DNS lookup feature on JB, + // we need to set the default DNS interface whenever setting the + // DNS name server. setDefaultInterface, + #endif setInterfaceDns, defaultAsyncSuccessHandler }; @@ -1898,6 +1904,17 @@ CommandResult NetworkUtils::setDefaultRouteLegacy(NetworkParams& aOptions) } } + // Set the default DNS interface. + if (SDK_VERSION >= 18) { + // For JB, KK only. + static CommandFunc COMMAND_CHAIN[] = { + setDefaultInterface, + defaultAsyncSuccessHandler + }; + runChain(aOptions, COMMAND_CHAIN, setDnsFail); + return CommandResult::Pending(); + } + return SUCCESS; } @@ -2516,6 +2533,27 @@ CommandResult NetworkUtils::destroyNetwork(NetworkParams& aOptions) return CommandResult::Pending(); } +/** + * Query the netId associated with the given network interface name. + */ +CommandResult NetworkUtils::getNetId(NetworkParams& aOptions) +{ + NetworkResultOptions result; + + if (SDK_VERSION < 20) { + // For pre-Lollipop, use the interface name as the fallback. + result.mNetId = GET_FIELD(mIfname); + return result; + } + + NetIdManager::NetIdInfo netIdInfo; + if (-1 == mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) { + return ESRCH; + } + result.mNetId.AppendInt(netIdInfo.mNetId, 10); + return result; +} + void NetworkUtils::sendBroadcastMessage(uint32_t code, char* reason) { NetworkResultOptions result; diff --git a/dom/system/gonk/NetworkUtils.h b/dom/system/gonk/NetworkUtils.h index e1bef5cc021c..db6cb104de23 100644 --- a/dom/system/gonk/NetworkUtils.h +++ b/dom/system/gonk/NetworkUtils.h @@ -309,6 +309,7 @@ private: CommandResult updateUpStream(NetworkParams& aOptions); CommandResult createNetwork(NetworkParams& aOptions); CommandResult destroyNetwork(NetworkParams& aOptions); + CommandResult getNetId(NetworkParams& aOptions); CommandResult addHostRouteLegacy(NetworkParams& aOptions); CommandResult removeHostRouteLegacy(NetworkParams& aOptions); diff --git a/dom/system/gonk/nsINetworkService.idl b/dom/system/gonk/nsINetworkService.idl index 9ad56122cc47..8db4aabb9614 100644 --- a/dom/system/gonk/nsINetworkService.idl +++ b/dom/system/gonk/nsINetworkService.idl @@ -159,7 +159,7 @@ interface nsIDhcpRequestCallback : nsISupports /** * Provide network services. */ -[scriptable, uuid(e40dd966-cb04-4dc7-ac4b-6382769c00b9)] +[scriptable, uuid(a0f29630-c25c-11e4-8830-0800200c9a66)] interface nsINetworkService : nsISupports { const long MODIFY_ROUTE_ADD = 0; @@ -486,4 +486,17 @@ interface nsINetworkService : nsISupports */ void destroyNetwork(in DOMString interfaceName, in nsINativeCommandCallback callback); + + /** + * Query the netId associated with given network interface name. + * + * @param interfaceName + * The network interface name which we want to query. + * + * @return A deferred promise that resolves with a string to indicate. + * the queried netId on success and rejects if the interface name + * is invalid. + * + */ + jsval getNetId(in DOMString interfaceName); }; diff --git a/dom/webidl/BluetoothAttributeEvent.webidl b/dom/webidl/BluetoothAttributeEvent.webidl index ca30bf89e4b5..dfeaa28ea531 100644 --- a/dom/webidl/BluetoothAttributeEvent.webidl +++ b/dom/webidl/BluetoothAttributeEvent.webidl @@ -9,13 +9,11 @@ optional BluetoothAttributeEventInit eventInitDict)] interface BluetoothAttributeEvent : Event { - readonly attribute any attrs; - // We don't support sequence in event codegen yet (Bug 1023762) - // Bug 1015796: - // readonly attribute sequence attrs; + [Cached, Constant] + readonly attribute sequence attrs; }; dictionary BluetoothAttributeEventInit : EventInit { - any attrs = null; + required sequence attrs; }; diff --git a/dom/webidl/NetworkOptions.webidl b/dom/webidl/NetworkOptions.webidl index c9df8a48278f..07d0438b6a7a 100644 --- a/dom/webidl/NetworkOptions.webidl +++ b/dom/webidl/NetworkOptions.webidl @@ -96,4 +96,6 @@ dictionary NetworkResultOptions long dns1 = 0; long dns2 = 0; long server = 0; + + DOMString netId = ""; // for "getNetId". }; diff --git a/dom/xbl/nsXBLPrototypeHandler.cpp b/dom/xbl/nsXBLPrototypeHandler.cpp index 24f8f6526307..bfa07e8b01d2 100644 --- a/dom/xbl/nsXBLPrototypeHandler.cpp +++ b/dom/xbl/nsXBLPrototypeHandler.cpp @@ -24,7 +24,6 @@ #include "nsIDOMHTMLTextAreaElement.h" #include "nsIDOMHTMLInputElement.h" #include "nsFocusManager.h" -#include "nsIFormControl.h" #include "nsIDOMEventListener.h" #include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" @@ -477,17 +476,34 @@ nsXBLPrototypeHandler::DispatchXBLCommand(EventTarget* aTarget, nsIDOMEvent* aEv nsFocusManager::GetFocusedDescendant(windowToCheck, true, getter_AddRefs(focusedWindow)); } - // If the focus is in an editable region, don't scroll. - if (focusedContent->IsEditable()) { - return NS_OK; - } + bool isLink = false; + nsIContent *content = focusedContent; - // If the focus is in a form control, don't scroll. - for (nsIContent* c = focusedContent; c; c = c->GetParent()) { - nsCOMPtr formControl = do_QueryInterface(c); - if (formControl) { - return NS_OK; + // if the focused element is a link then we do want space to + // scroll down. The focused element may be an element in a link, + // we need to check the parent node too. Only do this check if an + // element is focused and has a parent. + if (focusedContent && focusedContent->GetParent()) { + while (content) { + if (content->IsHTMLElement(nsGkAtoms::a)) { + isLink = true; + break; + } + + if (content->HasAttr(kNameSpaceID_XLink, nsGkAtoms::type)) { + isLink = content->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type, + nsGkAtoms::simple, eCaseMatters); + + if (isLink) { + break; + } + } + + content = content->GetParent(); } + + if (!isLink) + return NS_OK; } } diff --git a/editor/libeditor/tests/file_bug915962.html b/editor/libeditor/tests/file_bug915962.html deleted file mode 100644 index 85c5139d3b50..000000000000 --- a/editor/libeditor/tests/file_bug915962.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - -

- - diff --git a/editor/libeditor/tests/mochitest.ini b/editor/libeditor/tests/mochitest.ini index 982cf608bf50..e4472c1589f4 100644 --- a/editor/libeditor/tests/mochitest.ini +++ b/editor/libeditor/tests/mochitest.ini @@ -9,7 +9,6 @@ support-files = file_bug549262.html file_bug586662.html file_bug674770-1.html - file_bug915962.html file_select_all_without_body.html green.png spellcheck.js @@ -138,8 +137,6 @@ skip-if = toolkit == 'android' || e10s [test_bug832025.html] [test_bug857487.html] [test_bug858918.html] -[test_bug915962.html] -skip-if = toolkit == 'android' || e10s [test_bug966155.html] skip-if = os != "win" [test_bug966552.html] diff --git a/editor/libeditor/tests/test_bug915962.html b/editor/libeditor/tests/test_bug915962.html deleted file mode 100644 index af6f850b5c1a..000000000000 --- a/editor/libeditor/tests/test_bug915962.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Test for Bug 915962 - - - - - -Mozilla Bug 915962 -

-
-
-
-
-
- - diff --git a/editor/reftests/reftest.list b/editor/reftests/reftest.list index 744058f8a3a4..02ccd8f2fa5d 100644 --- a/editor/reftests/reftest.list +++ b/editor/reftests/reftest.list @@ -77,7 +77,7 @@ skip-if(B2G||Mulet) fails-if(Android) needs-focus != spellcheck-hyphen-multiple- == unneeded_scroll.html unneeded_scroll-ref.html skip-if(B2G||Mulet) == caret_on_presshell_reinit.html caret_on_presshell_reinit-ref.html # Initial mulet triage: parity with B2G/B2G Desktop skip-if(B2G||Mulet) == caret_on_presshell_reinit-2.html caret_on_presshell_reinit-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -skip-if(B2G||Mulet) == 642800.html 642800-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) skip-if(asyncPanZoom&&winWidget) == 642800.html 642800-ref.html # Initial mulet triage: parity with B2G/B2G Desktop == selection_visibility_after_reframe.html selection_visibility_after_reframe-ref.html != selection_visibility_after_reframe-2.html selection_visibility_after_reframe-ref.html != selection_visibility_after_reframe-3.html selection_visibility_after_reframe-ref.html diff --git a/gfx/2d/NumericTools.h b/gfx/2d/NumericTools.h index a1004e17bc3d..03aa7a8e28fe 100644 --- a/gfx/2d/NumericTools.h +++ b/gfx/2d/NumericTools.h @@ -6,10 +6,14 @@ #ifndef MOZILLA_GFX_NUMERICTOOLS_H_ #define MOZILLA_GFX_NUMERICTOOLS_H_ +namespace mozilla { + +// XXX - Move these into mfbt/MathAlgorithms.h? + // Returns the largest multiple of aMultiplied that's <= x. // Same as int32_t(floor(double(x) / aMultiplier)) * aMultiplier, // but faster. -static int32_t +inline int32_t RoundDownToMultiple(int32_t x, int32_t aMultiplier) { // We don't use float division + floor because that's hard for the compiler @@ -24,7 +28,7 @@ RoundDownToMultiple(int32_t x, int32_t aMultiplier) // Returns the smallest multiple of aMultiplied that's >= x. // Same as int32_t(ceil(double(x) / aMultiplier)) * aMultiplier, // but faster. -static int32_t +inline int32_t RoundUpToMultiple(int32_t x, int32_t aMultiplier) { int mod = x % aMultiplier; @@ -34,4 +38,6 @@ RoundUpToMultiple(int32_t x, int32_t aMultiplier) return x - mod; } +} // namespace mozilla + #endif /* MOZILLA_GFX_NUMERICTOOLS_H_ */ diff --git a/gfx/2d/Rect.h b/gfx/2d/Rect.h index c102e501b616..95828d3a7b7b 100644 --- a/gfx/2d/Rect.h +++ b/gfx/2d/Rect.h @@ -8,6 +8,7 @@ #include "BaseRect.h" #include "BaseMargin.h" +#include "NumericTools.h" #include "Point.h" #include "Tools.h" @@ -105,6 +106,21 @@ struct IntRectTyped : { return IntRectTyped::IsEqualEdges(aRect); } + + void InflateToMultiple(const IntSizeTyped& aTileSize) + { + int32_t yMost = this->YMost(); + int32_t xMost = this->XMost(); + + this->x = mozilla::RoundDownToMultiple(this->x, aTileSize.width); + this->y = mozilla::RoundDownToMultiple(this->y, aTileSize.height); + xMost = mozilla::RoundUpToMultiple(xMost, aTileSize.width); + yMost = mozilla::RoundUpToMultiple(yMost, aTileSize.height); + + this->width = xMost - this->x; + this->height = yMost - this->y; + } + }; typedef IntRectTyped IntRect; diff --git a/gfx/gl/GLTextureImage.cpp b/gfx/gl/GLTextureImage.cpp index 54f2f773b4f3..1bfcad6c3332 100644 --- a/gfx/gl/GLTextureImage.cpp +++ b/gfx/gl/GLTextureImage.cpp @@ -79,7 +79,7 @@ TextureImage::UpdateFromDataSource(gfx::DataSourceSurface *aSurface, const gfx::IntPoint* aSrcPoint) { nsIntRegion destRegion = aDestRegion ? *aDestRegion - : nsIntRect(0, 0, + : IntRect(0, 0, aSurface->GetSize().width, aSurface->GetSize().height); gfx::IntPoint srcPoint = aSrcPoint ? *aSrcPoint @@ -120,13 +120,13 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion) if (CanUploadSubTextures(mGLContext)) { GetUpdateRegion(aRegion); } else { - aRegion = nsIntRect(nsIntPoint(0, 0), mSize); + aRegion = IntRect(IntPoint(0, 0), mSize); } mUpdateRegion = aRegion; - nsIntRect rgnSize = mUpdateRegion.GetBounds(); - if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(rgnSize)) { + IntRect rgnSize = mUpdateRegion.GetBounds(); + if (!IntRect(IntPoint(0, 0), mSize).Contains(rgnSize)) { NS_ERROR("update outside of image"); return nullptr; } @@ -147,7 +147,7 @@ BasicTextureImage::GetUpdateRegion(nsIntRegion& aForRegion) // changed, we need to recreate our backing surface and force the // client to paint everything if (mTextureState != Valid) { - aForRegion = nsIntRect(nsIntPoint(0, 0), mSize); + aForRegion = IntRect(IntPoint(0, 0), mSize); } } @@ -205,10 +205,10 @@ BasicTextureImage::FinishedSurfaceUpload() bool BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0, 0) */) { - nsIntRect bounds = aRegion.GetBounds(); + IntRect bounds = aRegion.GetBounds(); nsIntRegion region; if (mTextureState != Valid) { - bounds = nsIntRect(0, 0, mSize.width, mSize.height); + bounds = IntRect(0, 0, mSize.width, mSize.height); region = nsIntRegion(bounds); } else { region = aRegion; @@ -220,7 +220,7 @@ BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion region, mTexture, mTextureState == Created, - bounds.TopLeft() + nsIntPoint(aFrom.x, aFrom.y), + bounds.TopLeft() + IntPoint(aFrom.x, aFrom.y), false); mTextureState = Valid; return true; @@ -345,7 +345,7 @@ TiledTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion nsIntRegion region; if (mTextureState != Valid) { - nsIntRect bounds = nsIntRect(0, 0, mSize.width, mSize.height); + IntRect bounds = IntRect(0, 0, mSize.width, mSize.height); region = nsIntRegion(bounds); } else { region = aRegion; @@ -355,7 +355,7 @@ TiledTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion int oldCurrentImage = mCurrentImage; BeginBigImageIteration(); do { - nsIntRect tileRect = ThebesIntRect(GetSrcTileRect()); + IntRect tileRect = GetSrcTileRect(); int xPos = tileRect.x; int yPos = tileRect.y; @@ -400,7 +400,7 @@ TiledTextureImage::GetUpdateRegion(nsIntRegion& aForRegion) // if the texture hasn't been initialized yet, or something important // changed, we need to recreate our backing surface and force the // client to paint everything - aForRegion = nsIntRect(nsIntPoint(0, 0), mSize); + aForRegion = IntRect(IntPoint(0, 0), mSize); return; } @@ -411,7 +411,7 @@ TiledTextureImage::GetUpdateRegion(nsIntRegion& aForRegion) for (unsigned i = 0; i < mImages.Length(); i++) { int xPos = (i % mColumns) * mTileSize; int yPos = (i / mColumns) * mTileSize; - nsIntRect imageRect = nsIntRect(nsIntPoint(xPos,yPos), + IntRect imageRect = IntRect(IntPoint(xPos,yPos), mImages[i]->GetSize()); if (aForRegion.Intersects(imageRect)) { @@ -446,16 +446,16 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion) // if the texture hasn't been initialized yet, or something important // changed, we need to recreate our backing surface and force the // client to paint everything - aRegion = nsIntRect(nsIntPoint(0, 0), mSize); + aRegion = IntRect(IntPoint(0, 0), mSize); } - nsIntRect bounds = aRegion.GetBounds(); + IntRect bounds = aRegion.GetBounds(); for (unsigned i = 0; i < mImages.Length(); i++) { int xPos = (i % mColumns) * mTileSize; int yPos = (i / mColumns) * mTileSize; nsIntRegion imageRegion = - nsIntRegion(nsIntRect(nsIntPoint(xPos,yPos), + nsIntRegion(IntRect(IntPoint(xPos,yPos), mImages[i]->GetSize())); // a single Image can handle this update request @@ -510,8 +510,7 @@ TiledTextureImage::EndUpdate() for (unsigned i = 0; i < mImages.Length(); i++) { int xPos = (i % mColumns) * mTileSize; int yPos = (i / mColumns) * mTileSize; - nsIntRect imageRect = nsIntRect(nsIntPoint(xPos,yPos), - mImages[i]->GetSize()); + IntRect imageRect = IntRect(IntPoint(xPos,yPos), mImages[i]->GetSize()); nsIntRegion subregion; subregion.And(mUpdateRegion, imageRect); diff --git a/gfx/gl/GLUploadHelpers.cpp b/gfx/gl/GLUploadHelpers.cpp index 8b1a3fcea06a..3cf04691d9a3 100644 --- a/gfx/gl/GLUploadHelpers.cpp +++ b/gfx/gl/GLUploadHelpers.cpp @@ -50,7 +50,7 @@ NextPowerOfTwo(int aNumber) } static unsigned int -DataOffset(const nsIntPoint &aPoint, int32_t aStride, SurfaceFormat aFormat) +DataOffset(const IntPoint &aPoint, int32_t aStride, SurfaceFormat aFormat) { unsigned int data = aPoint.y * aStride; data += aPoint.x * BytesPerPixel(aFormat); @@ -502,10 +502,10 @@ UploadImageDataToTexture(GLContext* gl, } nsIntRegionRectIterator iter(paintRegion); - const nsIntRect *iterRect; + const IntRect *iterRect; // Top left point of the region's bounding rectangle. - nsIntPoint topLeft = paintRegion.GetBounds().TopLeft(); + IntPoint topLeft = paintRegion.GetBounds().TopLeft(); while ((iterRect = iter.Next())) { // The inital data pointer is at the top left point of the region's @@ -556,7 +556,7 @@ UploadSurfaceToTexture(GLContext* gl, const nsIntRegion& aDstRegion, GLuint& aTexture, bool aOverwrite, - const nsIntPoint& aSrcPoint, + const gfx::IntPoint& aSrcPoint, bool aPixelBuffer, GLenum aTextureUnit, GLenum aTextureTarget) diff --git a/gfx/gl/GLUploadHelpers.h b/gfx/gl/GLUploadHelpers.h index 239e743d051e..1f41b9457791 100644 --- a/gfx/gl/GLUploadHelpers.h +++ b/gfx/gl/GLUploadHelpers.h @@ -74,7 +74,7 @@ UploadSurfaceToTexture(GLContext* gl, const nsIntRegion& aDstRegion, GLuint& aTexture, bool aOverwrite = false, - const nsIntPoint& aSrcPoint = nsIntPoint(0, 0), + const gfx::IntPoint& aSrcPoint = gfx::IntPoint(0, 0), bool aPixelBuffer = false, GLenum aTextureUnit = LOCAL_GL_TEXTURE0, GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D); diff --git a/gfx/gl/TextureImageEGL.cpp b/gfx/gl/TextureImageEGL.cpp index 9380d0a4828b..7d9d519e1200 100644 --- a/gfx/gl/TextureImageEGL.cpp +++ b/gfx/gl/TextureImageEGL.cpp @@ -102,7 +102,7 @@ TextureImageEGL::GetUpdateRegion(nsIntRegion& aForRegion) if (mTextureState != Valid) { // if the texture hasn't been initialized yet, force the // client to paint everything - aForRegion = nsIntRect(nsIntPoint(0, 0), mSize); + aForRegion = gfx::IntRect(gfx::IntPoint(0, 0), mSize); } // We can only draw a rectangle, not subregions due to @@ -122,7 +122,7 @@ TextureImageEGL::BeginUpdate(nsIntRegion& aRegion) mUpdateRect = aRegion.GetBounds(); //printf_stderr("BeginUpdate with updateRect [%d %d %d %d]\n", mUpdateRect.x, mUpdateRect.y, mUpdateRect.width, mUpdateRect.height); - if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) { + if (!gfx::IntRect(gfx::IntPoint(0, 0), mSize).Contains(mUpdateRect)) { NS_ERROR("update outside of image"); return nullptr; } @@ -198,11 +198,11 @@ TextureImageEGL::EndUpdate() bool TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0,0) */) { - nsIntRect bounds = aRegion.GetBounds(); + gfx::IntRect bounds = aRegion.GetBounds(); nsIntRegion region; if (mTextureState != Valid) { - bounds = nsIntRect(0, 0, mSize.width, mSize.height); + bounds = gfx::IntRect(0, 0, mSize.width, mSize.height); region = nsIntRegion(bounds); } else { region = aRegion; @@ -214,7 +214,7 @@ TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& region, mTexture, mTextureState == Created, - bounds.TopLeft() + nsIntPoint(aFrom.x, aFrom.y), + bounds.TopLeft() + gfx::IntPoint(aFrom.x, aFrom.y), false); mTextureState = Valid; diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index a678137fb8f0..ab4c94299444 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -391,28 +391,6 @@ struct ParamTraits > } }; -template<> -struct ParamTraits -{ - typedef nsIntRect paramType; - - static void Write(Message* msg, const paramType& param) - { - WriteParam(msg, param.x); - WriteParam(msg, param.y); - WriteParam(msg, param.width); - WriteParam(msg, param.height); - } - - static bool Read(const Message* msg, void** iter, paramType* result) - { - return (ReadParam(msg, iter, &result->x) && - ReadParam(msg, iter, &result->y) && - ReadParam(msg, iter, &result->width) && - ReadParam(msg, iter, &result->height)); - } -}; - template struct RegionParamTraits { diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp index 56a8f08bf070..c0f476846675 100644 --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -21,8 +21,7 @@ #include "nsDebug.h" // for NS_ASSERTION #include "nsHashKeys.h" // for nsPtrHashKey #include "nsISupportsImpl.h" // for Layer::AddRef, etc -#include "nsPoint.h" // for nsIntPoint -#include "nsRect.h" // for nsIntRect +#include "nsRect.h" // for IntRect #include "nsTArray.h" // for nsAutoTArray, nsTArray_Impl using namespace mozilla::gfx; @@ -33,20 +32,20 @@ namespace layers { struct LayerPropertiesBase; UniquePtr CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask = false); -static nsIntRect -TransformRect(const nsIntRect& aRect, const Matrix4x4& aTransform) +static IntRect +TransformRect(const IntRect& aRect, const Matrix4x4& aTransform) { if (aRect.IsEmpty()) { - return nsIntRect(); + return IntRect(); } Rect rect(aRect.x, aRect.y, aRect.width, aRect.height); rect = aTransform.TransformBounds(rect); rect.RoundOut(); - nsIntRect intRect; + IntRect intRect; if (!gfxUtils::GfxRectToIntRect(ThebesRect(rect), &intRect)) { - return nsIntRect(); + return IntRect(); } return intRect; @@ -56,7 +55,7 @@ static void AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4& aTransform) { nsIntRegionRectIterator iter(aSource); - const nsIntRect *r; + const IntRect *r; while ((r = iter.Next())) { aDest.Or(aDest, TransformRect(*r, aTransform)); } @@ -127,12 +126,12 @@ struct LayerPropertiesBase : public LayerProperties { MOZ_COUNT_DTOR(LayerPropertiesBase); } - - virtual nsIntRegion ComputeDifferences(Layer* aRoot, + + virtual nsIntRegion ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFunc aCallback, bool* aGeometryChanged); - virtual void MoveBy(const nsIntPoint& aOffset); + virtual void MoveBy(const IntPoint& aOffset); nsIntRegion ComputeChange(NotifySubDocInvalidationFunc aCallback, bool& aGeometryChanged) @@ -176,12 +175,12 @@ struct LayerPropertiesBase : public LayerProperties return result; } - nsIntRect NewTransformedBounds() + IntRect NewTransformedBounds() { return TransformRect(mLayer->GetVisibleRegion().GetBounds(), mLayer->GetLocalTransform()); } - nsIntRect OldTransformedBounds() + IntRect OldTransformedBounds() { return TransformRect(mVisibleRegion.GetBounds(), mTransform); } @@ -189,7 +188,7 @@ struct LayerPropertiesBase : public LayerProperties virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback, bool& aGeometryChanged) { - return nsIntRect(); + return IntRect(); } nsRefPtr mLayer; @@ -351,7 +350,7 @@ struct ColorLayerProperties : public LayerPropertiesBase } gfxRGBA mColor; - nsIntRect mBounds; + IntRect mBounds; }; struct ImageLayerProperties : public LayerPropertiesBase @@ -373,7 +372,7 @@ struct ImageLayerProperties : public LayerPropertiesBase if (!imageLayer->GetVisibleRegion().IsEqual(mVisibleRegion)) { aGeometryChanged = true; - nsIntRect result = NewTransformedBounds(); + IntRect result = NewTransformedBounds(); result = result.Union(OldTransformedBounds()); return result; } @@ -389,7 +388,7 @@ struct ImageLayerProperties : public LayerPropertiesBase // Mask layers have an empty visible region, so we have to // use the image size instead. IntSize size = container->GetCurrentSize(); - nsIntRect rect(0, 0, size.width, size.height); + IntRect rect(0, 0, size.width, size.height); return TransformRect(rect, mLayer->GetLocalTransform()); } else { @@ -397,7 +396,7 @@ struct ImageLayerProperties : public LayerPropertiesBase } } - return nsIntRect(); + return IntRect(); } nsRefPtr mContainer; @@ -466,7 +465,7 @@ LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFu } else { ClearInvalidations(aRoot); } - nsIntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(), + IntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(), aRoot->GetLocalTransform()); result = result.Union(OldTransformedBounds()); if (aGeometryChanged != nullptr) { @@ -484,7 +483,7 @@ LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFu } void -LayerPropertiesBase::MoveBy(const nsIntPoint& aOffset) +LayerPropertiesBase::MoveBy(const IntPoint& aOffset) { mTransform.PostTranslate(aOffset.x, aOffset.y, 0); } diff --git a/gfx/layers/LayerTreeInvalidation.h b/gfx/layers/LayerTreeInvalidation.h index ab71b65e554c..1d6b2af0fe70 100644 --- a/gfx/layers/LayerTreeInvalidation.h +++ b/gfx/layers/LayerTreeInvalidation.h @@ -8,9 +8,9 @@ #include "nsRegion.h" // for nsIntRegion #include "mozilla/UniquePtr.h" // for UniquePtr +#include "mozilla/gfx/Point.h" class nsPresContext; -struct nsIntPoint; namespace mozilla { namespace layers { @@ -59,12 +59,11 @@ struct LayerProperties * are invalidated. * @return Painted area changed by the layer tree changes. */ - virtual nsIntRegion ComputeDifferences(Layer* aRoot, + virtual nsIntRegion ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFunc aCallback, bool* aGeometryChanged = nullptr) = 0; - - - virtual void MoveBy(const nsIntPoint& aOffset) = 0; + + virtual void MoveBy(const gfx::IntPoint& aOffset) = 0; }; } // namespace layers diff --git a/gfx/layers/LayersLogging.h b/gfx/layers/LayersLogging.h index 00f66d6f3127..97498a2c6ff9 100644 --- a/gfx/layers/LayersLogging.h +++ b/gfx/layers/LayersLogging.h @@ -17,8 +17,6 @@ #include "nscore.h" // for nsACString, etc struct gfxRGBA; -struct nsIntPoint; -struct nsIntRect; namespace mozilla { namespace gfx { @@ -52,10 +50,6 @@ void AppendToString(std::stringstream& aStream, const nsRect& r, const char* pfx="", const char* sfx=""); -void -AppendToString(std::stringstream& aStream, const nsIntPoint& p, - const char* pfx="", const char* sfx=""); - template void AppendToString(std::stringstream& aStream, const mozilla::gfx::PointTyped& p, @@ -72,10 +66,6 @@ AppendToString(std::stringstream& aStream, const mozilla::gfx::IntPointTyped& aStream << pfx << p << sfx; } -void -AppendToString(std::stringstream& aStream, const nsIntRect& r, - const char* pfx="", const char* sfx=""); - template void AppendToString(std::stringstream& aStream, const mozilla::gfx::RectTyped& r, diff --git a/gfx/layers/ReadbackLayer.h b/gfx/layers/ReadbackLayer.h index 3e72ce941c99..f9de30bb4f34 100644 --- a/gfx/layers/ReadbackLayer.h +++ b/gfx/layers/ReadbackLayer.h @@ -9,14 +9,13 @@ #include // for uint64_t #include "Layers.h" // for Layer, etc #include "gfxColor.h" // for gfxRGBA -#include "gfxRect.h" // for gfxRect +#include "mozilla/gfx/Rect.h" // for gfxRect +#include "mozilla/gfx/Point.h" // for gfxRect #include "mozilla/mozalloc.h" // for operator delete #include "nsAutoPtr.h" // for nsAutoPtr #include "nsCOMPtr.h" // for already_AddRefed #include "nsDebug.h" // for NS_ASSERTION #include "nsPoint.h" // for nsIntPoint -#include "nsRect.h" // for nsIntRect -#include "nsSize.h" // for nsIntSize #include "nscore.h" // for nsACString class gfxContext; @@ -61,14 +60,14 @@ public: * first BeginUpdate after a SetUnknown will have the complete background. */ virtual already_AddRefed - BeginUpdate(const nsIntRect& aRect, uint64_t aSequenceNumber) = 0; + BeginUpdate(const gfx::IntRect& aRect, uint64_t aSequenceNumber) = 0; /** * EndUpdate must be called immediately after BeginUpdate, without returning * to the event loop. * @param aContext the context returned by BeginUpdate * Implicitly Restore()s the state of aContext. */ - virtual void EndUpdate(gfxContext* aContext, const nsIntRect& aRect) = 0; + virtual void EndUpdate(gfxContext* aContext, const gfx::IntRect& aRect) = 0; }; /** @@ -122,13 +121,13 @@ public: * has its top-left at 0,0 and has size aSize. * Can only be called while the sink is null! */ - void SetSize(const nsIntSize& aSize) + void SetSize(const gfx::IntSize& aSize) { NS_ASSERTION(!mSink, "Should have no sink while changing size!"); mSize = aSize; } - const nsIntSize& GetSize() { return mSize; } - nsIntRect GetRect() { return nsIntRect(nsIntPoint(0, 0), mSize); } + const gfx::IntSize& GetSize() { return mSize; } + gfx::IntRect GetRect() { return gfx::IntRect(gfx::IntPoint(0, 0), mSize); } bool IsBackgroundKnown() { @@ -180,7 +179,7 @@ protected: uint64_t mSequenceCounter; nsAutoPtr mSink; - nsIntSize mSize; + gfx::IntSize mSize; // This can refer to any (earlier) sibling PaintedLayer. That PaintedLayer // must have mUsedForReadback set on it. If the PaintedLayer is removed diff --git a/gfx/layers/RotatedBuffer.cpp b/gfx/layers/RotatedBuffer.cpp index 754a9fef6fad..e4430f4edaf5 100644 --- a/gfx/layers/RotatedBuffer.cpp +++ b/gfx/layers/RotatedBuffer.cpp @@ -34,12 +34,12 @@ using namespace gfx; namespace layers { -nsIntRect +IntRect RotatedBuffer::GetQuadrantRectangle(XSide aXSide, YSide aYSide) const { // quadrantTranslation is the amount we translate the top-left // of the quadrant by to get coordinates relative to the layer - nsIntPoint quadrantTranslation = -mBufferRotation; + IntPoint quadrantTranslation = -mBufferRotation; quadrantTranslation.x += aXSide == LEFT ? mBufferRect.width : 0; quadrantTranslation.y += aYSide == TOP ? mBufferRect.height : 0; return mBufferRect + quadrantTranslation; @@ -89,8 +89,8 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget, // render the buffer at mBufferRect + quadrantTranslation to get the // pixels in the right place, but we're only going to paint within // mBufferRect - nsIntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide); - nsIntRect fillRect; + IntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide); + IntRect fillRect; if (!fillRect.IntersectRect(mBufferRect, quadrantRect)) return; @@ -241,11 +241,11 @@ RotatedContentBuffer::DrawTo(PaintedLayer* aLayer, } DrawTarget* -RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds, +RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const IntRect& aBounds, ContextSource aSource, DrawIterator* aIter) { - nsIntRect bounds = aBounds; + IntRect bounds = aBounds; if (aIter) { // If an iterator was provided, then BeginPaint must have been run with // PAINT_CAN_DRAW_ROTATED, and the draw region might cover multiple quadrants. @@ -254,7 +254,7 @@ RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds // quadrants we have considered across multiple calls to this function. aIter->mDrawRegion.SetEmpty(); while (aIter->mCount < 4) { - nsIntRect quadrant = GetQuadrantRectangle((aIter->mCount & 1) ? LEFT : RIGHT, + IntRect quadrant = GetQuadrantRectangle((aIter->mCount & 1) ? LEFT : RIGHT, (aIter->mCount & 2) ? TOP : BOTTOM); aIter->mDrawRegion.And(aBounds, quadrant); aIter->mCount++; @@ -294,7 +294,7 @@ RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y; XSide sideX = bounds.XMost() <= xBoundary ? RIGHT : LEFT; YSide sideY = bounds.YMost() <= yBoundary ? BOTTOM : TOP; - nsIntRect quadrantRect = GetQuadrantRectangle(sideX, sideY); + IntRect quadrantRect = GetQuadrantRectangle(sideX, sideY); NS_ASSERTION(quadrantRect.Contains(bounds), "Messed up quadrants"); mLoanedTransform = mLoanedDrawTarget->GetTransform(); @@ -390,10 +390,10 @@ WrapRotationAxis(int32_t* aRotationPoint, int32_t aSize) } } -static nsIntRect -ComputeBufferRect(const nsIntRect& aRequestedRect) +static IntRect +ComputeBufferRect(const IntRect& aRequestedRect) { - nsIntRect rect(aRequestedRect); + IntRect rect(aRequestedRect); // Set a minimum width to guarantee a minimum size of buffers we // allocate (and work around problems on some platforms with smaller // dimensions). 64 is the magic number needed to work around the @@ -447,7 +447,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, SurfaceMode mode; nsIntRegion neededRegion; - nsIntRect destBufferRect; + IntRect destBufferRect; bool canReuseBuffer = HaveBuffer(); @@ -464,7 +464,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, } else if (neededRegion.GetBounds().Size() <= mBufferRect.Size()) { // The buffer's big enough but doesn't contain everything that's // going to be visible. We'll move it. - destBufferRect = nsIntRect(neededRegion.GetBounds().TopLeft(), mBufferRect.Size()); + destBufferRect = IntRect(neededRegion.GetBounds().TopLeft(), mBufferRect.Size()); } else { destBufferRect = neededRegion.GetBounds(); } @@ -555,7 +555,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, FinalizeFrame(result.mRegionToDraw); } - nsIntRect drawBounds = result.mRegionToDraw.GetBounds(); + IntRect drawBounds = result.mRegionToDraw.GetBounds(); RefPtr destDTBuffer; RefPtr destDTBufferOnWhite; uint32_t bufferFlags = 0; @@ -566,40 +566,38 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, if (!EnsureBuffer()) { return result; } - nsIntRect keepArea; + IntRect keepArea; if (keepArea.IntersectRect(destBufferRect, mBufferRect)) { // Set mBufferRotation so that the pixels currently in mDTBuffer // will still be rendered in the right place when mBufferRect // changes to destBufferRect. - nsIntPoint newRotation = mBufferRotation + + IntPoint newRotation = mBufferRotation + (destBufferRect.TopLeft() - mBufferRect.TopLeft()); WrapRotationAxis(&newRotation.x, mBufferRect.width); WrapRotationAxis(&newRotation.y, mBufferRect.height); - NS_ASSERTION(nsIntRect(nsIntPoint(0,0), mBufferRect.Size()).Contains(newRotation), + NS_ASSERTION(gfx::IntRect(gfx::IntPoint(0,0), mBufferRect.Size()).Contains(newRotation), "newRotation out of bounds"); int32_t xBoundary = destBufferRect.XMost() - newRotation.x; int32_t yBoundary = destBufferRect.YMost() - newRotation.y; bool drawWrapsBuffer = (drawBounds.x < xBoundary && xBoundary < drawBounds.XMost()) || (drawBounds.y < yBoundary && yBoundary < drawBounds.YMost()); if ((drawWrapsBuffer && !(aFlags & PAINT_CAN_DRAW_ROTATED)) || - (newRotation != nsIntPoint(0,0) && !canHaveRotation)) { + (newRotation != IntPoint(0,0) && !canHaveRotation)) { // The stuff we need to redraw will wrap around an edge of the // buffer (and the caller doesn't know how to support that), so // move the pixels we can keep into a position that lets us // redraw in just one quadrant. - if (mBufferRotation == nsIntPoint(0,0)) { - nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size()); - nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft(); + if (mBufferRotation == IntPoint(0,0)) { + IntRect srcRect(IntPoint(0, 0), mBufferRect.Size()); + IntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft(); MOZ_ASSERT(mDTBuffer); - mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height), - IntPoint(dest.x, dest.y)); + mDTBuffer->CopyRect(srcRect, dest); if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) { if (!EnsureBufferOnWhite()) { return result; } MOZ_ASSERT(mDTBufferOnWhite); - mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height), - IntPoint(dest.x, dest.y)); + mDTBufferOnWhite->CopyRect(srcRect, dest); } result.mDidSelfCopy = true; mDidSelfCopy = true; @@ -641,7 +639,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, result.mDidSelfCopy = true; mDidSelfCopy = true; mBufferRect = destBufferRect; - mBufferRotation = nsIntPoint(0, 0); + mBufferRotation = IntPoint(0, 0); } if (!result.mDidSelfCopy) { @@ -664,7 +662,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, // will be redrawn, so we don't need to copy anything, so we don't // set destBuffer. mBufferRect = destBufferRect; - mBufferRotation = nsIntPoint(0,0); + mBufferRotation = IntPoint(0,0); } } else { // The buffer's not big enough, so allocate a new one @@ -687,7 +685,7 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, if (destDTBuffer) { if (!isClear && (mode != SurfaceMode::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) { // Copy the bits - nsIntPoint offset = -destBufferRect.TopLeft(); + IntPoint offset = -destBufferRect.TopLeft(); Matrix mat = Matrix::Translation(offset.x, offset.y); destDTBuffer->SetTransform(mat); if (!EnsureBuffer()) { @@ -711,9 +709,9 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer, mDTBuffer = destDTBuffer.forget(); mDTBufferOnWhite = destDTBufferOnWhite.forget(); mBufferRect = destBufferRect; - mBufferRotation = nsIntPoint(0,0); + mBufferRotation = IntPoint(0,0); } - NS_ASSERTION(canHaveRotation || mBufferRotation == nsIntPoint(0,0), + NS_ASSERTION(canHaveRotation || mBufferRotation == IntPoint(0,0), "Rotation disabled, but we have nonzero rotation?"); nsIntRegion invalidate; @@ -758,7 +756,7 @@ RotatedContentBuffer::BorrowDrawTargetForPainting(PaintState& aPaintState, return nullptr; } nsIntRegionRectIterator iter(*drawPtr); - const nsIntRect *iterRect; + const IntRect *iterRect; while ((iterRect = iter.Next())) { mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height), ColorPattern(Color(0.0, 0.0, 0.0, 1.0))); @@ -768,7 +766,7 @@ RotatedContentBuffer::BorrowDrawTargetForPainting(PaintState& aPaintState, } else if (aPaintState.mContentType == gfxContentType::COLOR_ALPHA && HaveBuffer()) { // HaveBuffer() => we have an existing buffer that we must clear nsIntRegionRectIterator iter(*drawPtr); - const nsIntRect *iterRect; + const IntRect *iterRect; while ((iterRect = iter.Next())) { result->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height)); } diff --git a/gfx/layers/RotatedBuffer.h b/gfx/layers/RotatedBuffer.h index fcf06e3a48ef..3dab3d349be9 100644 --- a/gfx/layers/RotatedBuffer.h +++ b/gfx/layers/RotatedBuffer.h @@ -16,8 +16,6 @@ #include "nsCOMPtr.h" // for already_AddRefed #include "nsDebug.h" // for NS_RUNTIMEABORT #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc -#include "nsPoint.h" // for nsIntPoint -#include "nsRect.h" // for nsIntRect #include "nsRegion.h" // for nsIntRegion #include "LayersTypes.h" @@ -50,8 +48,8 @@ class RotatedBuffer { public: typedef gfxContentType ContentType; - RotatedBuffer(const nsIntRect& aBufferRect, - const nsIntPoint& aBufferRotation) + RotatedBuffer(const gfx::IntRect& aBufferRect, + const gfx::IntPoint& aBufferRotation) : mBufferRect(aBufferRect) , mBufferRotation(aBufferRotation) , mDidSelfCopy(false) @@ -81,8 +79,8 @@ public: * RotatedBuffer covers. That is what DrawBufferWithRotation() * will paint when it's called. */ - const nsIntRect& BufferRect() const { return mBufferRect; } - const nsIntPoint& BufferRotation() const { return mBufferRotation; } + const gfx::IntRect& BufferRect() const { return mBufferRect; } + const gfx::IntPoint& BufferRotation() const { return mBufferRotation; } virtual bool HaveBuffer() const = 0; virtual bool HaveBufferOnWhite() const = 0; @@ -97,7 +95,7 @@ protected: enum YSide { TOP, BOTTOM }; - nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide) const; + gfx::IntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide) const; gfx::Rect GetSourceRectangle(XSide aXSide, YSide aYSide) const; @@ -114,7 +112,7 @@ protected: const gfx::Matrix* aMaskTransform) const; /** The area of the PaintedLayer that is covered by the buffer as a whole */ - nsIntRect mBufferRect; + gfx::IntRect mBufferRect; /** * The x and y rotation of the buffer. Conceptually the buffer * has its origin translated to mBufferRect.TopLeft() - mBufferRotation, @@ -125,7 +123,7 @@ protected: * where items falling off the end of the buffer are returned to the * buffer at the other end, not 2D rotation! */ - nsIntPoint mBufferRotation; + gfx::IntPoint mBufferRotation; // When this is true it means that all pixels have moved inside the buffer. // It's not possible to sync with another buffer without a full copy. bool mDidSelfCopy; @@ -135,8 +133,8 @@ class SourceRotatedBuffer : public RotatedBuffer { public: SourceRotatedBuffer(gfx::SourceSurface* aSource, gfx::SourceSurface* aSourceOnWhite, - const nsIntRect& aBufferRect, - const nsIntPoint& aBufferRotation) + const gfx::IntRect& aBufferRect, + const gfx::IntPoint& aBufferRotation) : RotatedBuffer(aBufferRect, aBufferRotation) , mSource(aSource) , mSourceOnWhite(aSourceOnWhite) @@ -310,7 +308,7 @@ public: * will be used. */ virtual void - CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags, + CreateBuffer(ContentType aType, const gfx::IntRect& aRect, uint32_t aFlags, RefPtr* aBlackDT, RefPtr* aWhiteDT) = 0; /** @@ -375,7 +373,7 @@ protected: * draw target, if necessary. */ gfx::DrawTarget* - BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds, + BorrowDrawTargetForQuadrantUpdate(const gfx::IntRect& aBounds, ContextSource aSource, DrawIterator* aIter); diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp index a0f5e99323b2..17d40d10e7cc 100644 --- a/gfx/layers/basic/BasicCompositor.cpp +++ b/gfx/layers/basic/BasicCompositor.cpp @@ -486,7 +486,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion, // Sometimes the invalid region is larger than we want to draw. nsIntRegion invalidRegionSafe; - invalidRegionSafe.And(aInvalidRegion, gfx::ThebesIntRect(intRect)); + invalidRegionSafe.And(aInvalidRegion, intRect); nsIntRect invalidRect = invalidRegionSafe.GetBounds(); mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height); diff --git a/gfx/layers/basic/BasicContainerLayer.cpp b/gfx/layers/basic/BasicContainerLayer.cpp index 116aaa3e37af..5e2b01fdb7c4 100644 --- a/gfx/layers/basic/BasicContainerLayer.cpp +++ b/gfx/layers/basic/BasicContainerLayer.cpp @@ -14,7 +14,6 @@ #include "nsCOMPtr.h" // for already_AddRefed #include "nsISupportsImpl.h" // for Layer::AddRef, etc #include "nsPoint.h" // for nsIntPoint -#include "nsRect.h" // for nsIntRect #include "nsRegion.h" // for nsIntRegion #include "ReadbackProcessor.h" @@ -78,7 +77,7 @@ BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSur } bool -BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect) +BasicContainerLayer::ChildrenPartitionVisibleRegion(const gfx::IntRect& aInRect) { Matrix transform; if (!GetEffectiveTransform().CanDraw2D(&transform) || @@ -86,7 +85,7 @@ BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect) return false; nsIntPoint offset(int32_t(transform._31), int32_t(transform._32)); - nsIntRect rect = aInRect.Intersect(GetEffectiveVisibleRegion().GetBounds() + offset); + gfx::IntRect rect = aInRect.Intersect(GetEffectiveVisibleRegion().GetBounds() + offset); nsIntRegion covered; for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) { diff --git a/gfx/layers/basic/BasicContainerLayer.h b/gfx/layers/basic/BasicContainerLayer.h index 4b7fbaa1d866..ef825a6efb9c 100644 --- a/gfx/layers/basic/BasicContainerLayer.h +++ b/gfx/layers/basic/BasicContainerLayer.h @@ -12,7 +12,7 @@ #include "nsDebug.h" // for NS_ASSERTION #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR #include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE -struct nsIntRect; +#include "mozilla/gfx/Rect.h" namespace mozilla { namespace layers { @@ -77,7 +77,7 @@ public: * This method can be conservative; it's OK to return false under any * circumstances. */ - bool ChildrenPartitionVisibleRegion(const nsIntRect& aInRect); + bool ChildrenPartitionVisibleRegion(const gfx::IntRect& aInRect); void ForceIntermediateSurface() { mUseIntermediateSurface = true; } diff --git a/gfx/layers/client/ClientTiledPaintedLayer.cpp b/gfx/layers/client/ClientTiledPaintedLayer.cpp index 942280b6c2bd..5c45f0f37f36 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.cpp +++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp @@ -18,7 +18,6 @@ #include "mozilla/layers/LayersMessages.h" #include "mozilla/mozalloc.h" // for operator delete, etc #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc -#include "nsRect.h" // for nsIntRect #include "LayersLogging.h" namespace mozilla { @@ -424,12 +423,12 @@ ClientTiledPaintedLayer::RenderLayer() // outside of our texture coords. Make the visible region a single rect, // and pad it out by 1 pixel (restricted to tile boundaries) so that // we always have valid content or transparent pixels to sample from. - nsIntRect bounds = neededRegion.GetBounds(); - nsIntRect wholeTiles = bounds; - wholeTiles.InflateToMultiple(nsIntSize( + IntRect bounds = neededRegion.GetBounds(); + IntRect wholeTiles = bounds; + wholeTiles.InflateToMultiple(IntSize( gfxPlatform::GetPlatform()->GetTileWidth(), gfxPlatform::GetPlatform()->GetTileHeight())); - nsIntRect padded = bounds; + IntRect padded = bounds; padded.Inflate(1); padded.IntersectRect(padded, wholeTiles); neededRegion = padded; diff --git a/gfx/layers/composite/CanvasLayerComposite.cpp b/gfx/layers/composite/CanvasLayerComposite.cpp index 4f2788cfe792..665c95a16cdd 100644 --- a/gfx/layers/composite/CanvasLayerComposite.cpp +++ b/gfx/layers/composite/CanvasLayerComposite.cpp @@ -17,7 +17,6 @@ #include "nsAString.h" #include "nsRefPtr.h" // for nsRefPtr #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc -#include "nsPoint.h" // for nsIntPoint #include "nsString.h" // for nsAutoCString #include "gfxVR.h" diff --git a/gfx/layers/composite/CanvasLayerComposite.h b/gfx/layers/composite/CanvasLayerComposite.h index b47c30cebf1f..db6bfbb86d08 100644 --- a/gfx/layers/composite/CanvasLayerComposite.h +++ b/gfx/layers/composite/CanvasLayerComposite.h @@ -14,7 +14,6 @@ #include "nsDebug.h" // for NS_RUNTIMEABORT #include "nsRect.h" // for nsIntRect #include "nscore.h" // for nsACString -struct nsIntPoint; namespace mozilla { namespace layers { diff --git a/gfx/layers/composite/ColorLayerComposite.cpp b/gfx/layers/composite/ColorLayerComposite.cpp index 231e93551884..cdc23320114b 100644 --- a/gfx/layers/composite/ColorLayerComposite.cpp +++ b/gfx/layers/composite/ColorLayerComposite.cpp @@ -14,20 +14,18 @@ #include "mozilla/layers/CompositorTypes.h" // for DiagnosticFlags::COLOR #include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc #include "mozilla/mozalloc.h" // for operator delete, etc -#include "nsPoint.h" // for nsIntPoint -#include "nsRect.h" // for nsIntRect namespace mozilla { namespace layers { void -ColorLayerComposite::RenderLayer(const nsIntRect& aClipRect) +ColorLayerComposite::RenderLayer(const gfx::IntRect& aClipRect) { EffectChain effects(this); GenEffectChain(effects); - nsIntRect boundRect = GetBounds(); + gfx::IntRect boundRect = GetBounds(); LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(GetMaskLayer(), effects); diff --git a/gfx/layers/composite/ColorLayerComposite.h b/gfx/layers/composite/ColorLayerComposite.h index f102028f7919..9f36e1e0872f 100644 --- a/gfx/layers/composite/ColorLayerComposite.h +++ b/gfx/layers/composite/ColorLayerComposite.h @@ -11,9 +11,6 @@ #include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite, etc #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc -struct nsIntPoint; -struct nsIntRect; - namespace mozilla { namespace layers { @@ -50,7 +47,7 @@ public: virtual void Destroy() override { mDestroyed = true; } - virtual void RenderLayer(const nsIntRect& aClipRect) override; + virtual void RenderLayer(const gfx::IntRect& aClipRect) override; virtual void CleanupResources() override {}; virtual void GenEffectChain(EffectChain& aEffect) override; diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index 526d3b387df1..3624ceb26965 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -28,9 +28,6 @@ #include "nscore.h" // for nsACString #include "Units.h" // for CSSToScreenScale -struct nsIntPoint; -struct nsIntRect; - namespace mozilla { namespace gfx { class Matrix4x4; @@ -108,7 +105,7 @@ public: virtual LayerRenderState GetRenderState() = 0; - virtual void SetPictureRect(const nsIntRect& aPictureRect) + virtual void SetPictureRect(const gfx::IntRect& aPictureRect) { MOZ_ASSERT(false, "Should have been overridden"); } diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index fef39072c1a9..bb911d91032c 100755 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -29,8 +29,6 @@ #include "nsDebug.h" // for NS_ASSERTION #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc #include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE -#include "nsPoint.h" // for nsIntPoint -#include "nsRect.h" // for nsIntRect #include "nsRegion.h" // for nsIntRegion #include "nsTArray.h" // for nsAutoTArray #include "TextRenderer.h" // for TextRenderer @@ -85,8 +83,8 @@ static void DrawLayerInfo(const RenderTargetIntRect& aClipRect, uint32_t maxWidth = std::min(visibleRegion.GetBounds().width, 500); - nsIntPoint topLeft = visibleRegion.GetBounds().TopLeft(); - aManager->GetTextRenderer()->RenderText(ss.str().c_str(), gfx::IntPoint(topLeft.x, topLeft.y), + IntPoint topLeft = visibleRegion.GetBounds().TopLeft(); + aManager->GetTextRenderer()->RenderText(ss.str().c_str(), topLeft, aLayer->GetEffectiveTransform(), 16, maxWidth); } @@ -94,9 +92,7 @@ static void DrawLayerInfo(const RenderTargetIntRect& aClipRect, template static gfx::IntRect ContainerVisibleRect(ContainerT* aContainer) { - nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); - gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y, - visibleRect.width, visibleRect.height); + gfx::IntRect surfaceRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); return surfaceRect; } @@ -137,7 +133,7 @@ struct PreparedLayer template void ContainerRenderVR(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect, + const gfx::IntRect& aClipRect, gfx::VRHMDInfo* aHMD) { RefPtr surface; @@ -146,7 +142,7 @@ ContainerRenderVR(ContainerT* aContainer, RefPtr previousTarget = compositor->GetCurrentRenderTarget(); - nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); + gfx::IntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); float opacity = aContainer->GetEffectiveOpacity(); @@ -176,7 +172,7 @@ ContainerRenderVR(ContainerT* aContainer, /** * Render this container's contents. */ - nsIntRect surfaceClipRect(0, 0, surfaceRect.width, surfaceRect.height); + gfx::IntRect surfaceClipRect(0, 0, surfaceRect.width, surfaceRect.height); RenderTargetIntRect rtClipRect(0, 0, surfaceRect.width, surfaceRect.height); for (uint32_t i = 0; i < children.Length(); i++) { LayerComposite* layerToRender = static_cast(children.ElementAt(i)->ImplData()); @@ -352,7 +348,7 @@ RenderLayers(ContainerT* aContainer, // intersect areas in different coordinate spaces. So we do this a little more permissively // and only fill in the background when we know there is checkerboard, which in theory // should only occur transiently. - nsIntRect layerBounds = layer->GetLayerBounds(); + gfx::IntRect layerBounds = layer->GetLayerBounds(); EffectChain effectChain(layer); effectChain.mPrimaryEffect = new EffectSolidColor(ToColor(color)); aManager->GetCompositor()->DrawQuad(gfx::Rect(layerBounds.x, layerBounds.y, layerBounds.width, layerBounds.height), @@ -365,12 +361,12 @@ RenderLayers(ContainerT* aContainer, // Composer2D will compose this layer so skip GPU composition // this time & reset composition flag for next composition phase layerToRender->SetLayerComposited(false); - nsIntRect clearRect = layerToRender->GetClearRect(); + gfx::IntRect clearRect = layerToRender->GetClearRect(); if (!clearRect.IsEmpty()) { // Clear layer's visible rect on FrameBuffer with transparent pixels gfx::Rect fbRect(clearRect.x, clearRect.y, clearRect.width, clearRect.height); compositor->ClearRect(fbRect); - layerToRender->SetClearRect(nsIntRect(0, 0, 0, 0)); + layerToRender->SetClearRect(gfx::IntRect(0, 0, 0, 0)); } } else { layerToRender->RenderLayer(RenderTargetPixel::ToUntyped(clipRect)); @@ -445,7 +441,7 @@ CreateTemporaryTargetAndCopyFromBackground(ContainerT* aContainer, LayerManagerComposite* aManager) { Compositor* compositor = aManager->GetCompositor(); - nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); + gfx::IntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); RefPtr previousTarget = compositor->GetCurrentRenderTarget(); gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); @@ -465,7 +461,7 @@ CreateTemporaryTargetAndCopyFromBackground(ContainerT* aContainer, template void RenderIntermediate(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect, + const gfx::IntRect& aClipRect, RefPtr surface) { Compositor* compositor = aManager->GetCompositor(); @@ -485,7 +481,7 @@ RenderIntermediate(ContainerT* aContainer, template void ContainerRender(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect) + const gfx::IntRect& aClipRect) { MOZ_ASSERT(aContainer->mPrepared); @@ -515,7 +511,7 @@ ContainerRender(ContainerT* aContainer, float opacity = aContainer->GetEffectiveOpacity(); - nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); + gfx::IntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { RefPtr surf = surface->Dump(aManager->GetCompositor()); @@ -614,7 +610,7 @@ ContainerLayerComposite::GetFirstChildComposite() } void -ContainerLayerComposite::RenderLayer(const nsIntRect& aClipRect) +ContainerLayerComposite::RenderLayer(const gfx::IntRect& aClipRect) { ContainerRender(this, mCompositeManager, aClipRect); } @@ -665,7 +661,7 @@ RefLayerComposite::GetFirstChildComposite() } void -RefLayerComposite::RenderLayer(const nsIntRect& aClipRect) +RefLayerComposite::RenderLayer(const gfx::IntRect& aClipRect) { ContainerRender(this, mCompositeManager, aClipRect); } diff --git a/gfx/layers/composite/ContainerLayerComposite.h b/gfx/layers/composite/ContainerLayerComposite.h index 642ed1939978..5621d24acc37 100644 --- a/gfx/layers/composite/ContainerLayerComposite.h +++ b/gfx/layers/composite/ContainerLayerComposite.h @@ -10,9 +10,7 @@ #include "mozilla/Attributes.h" // for override #include "mozilla/UniquePtr.h" // for UniquePtr #include "mozilla/layers/LayerManagerComposite.h" - -struct nsIntPoint; -struct nsIntRect; +#include "mozilla/gfx/Rect.h" namespace mozilla { namespace layers { @@ -39,7 +37,7 @@ class ContainerLayerComposite : public ContainerLayer, template friend void RenderIntermediate(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect, + const gfx::IntRect& aClipRect, RefPtr surface); template friend RefPtr @@ -77,7 +75,7 @@ public: LayerComposite* GetFirstChildComposite() override; - virtual void RenderLayer(const nsIntRect& aClipRect) override; + virtual void RenderLayer(const gfx::IntRect& aClipRect) override; virtual void Prepare(const RenderTargetIntRect& aClipRect) override; virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override @@ -126,26 +124,26 @@ class RefLayerComposite : public RefLayer, template friend void ContainerRender(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect); + const gfx::IntRect& aClipRect); template friend void RenderLayers(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect); + const gfx::IntRect& aClipRect); template friend void RenderIntermediate(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect, + const gfx::IntRect& aClipRect, RefPtr surface); template friend RefPtr CreateTemporaryTargetAndCopyFromBackground(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect); + const gfx::IntRect& aClipRect); template friend RefPtr CreateTemporaryTarget(ContainerT* aContainer, LayerManagerComposite* aManager, - const nsIntRect& aClipRect); + const gfx::IntRect& aClipRect); public: explicit RefLayerComposite(LayerManagerComposite *aManager); @@ -161,7 +159,7 @@ public: LayerComposite* GetFirstChildComposite() override; - virtual void RenderLayer(const nsIntRect& aClipRect) override; + virtual void RenderLayer(const gfx::IntRect& aClipRect) override; virtual void Prepare(const RenderTargetIntRect& aClipRect) override; virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override diff --git a/gfx/layers/composite/ContentHost.cpp b/gfx/layers/composite/ContentHost.cpp index 166184f778a7..a8d95341c1df 100644 --- a/gfx/layers/composite/ContentHost.cpp +++ b/gfx/layers/composite/ContentHost.cpp @@ -327,7 +327,7 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData, // Select only the pixels that are still within the buffer. nsIntRegion finalRegion; - finalRegion.And(nsIntRect(nsIntPoint(), bufferSize), destRegion); + finalRegion.And(IntRect(IntPoint(), bufferSize), destRegion); // For each of the overlap areas (right, bottom-right, bottom), select those // pixels and wrap them around to the opposite edge of the buffer rect. diff --git a/gfx/layers/composite/ImageLayerComposite.cpp b/gfx/layers/composite/ImageLayerComposite.cpp index afd630c5d76a..025ba722ba31 100644 --- a/gfx/layers/composite/ImageLayerComposite.cpp +++ b/gfx/layers/composite/ImageLayerComposite.cpp @@ -21,8 +21,6 @@ #include "nsRefPtr.h" // for nsRefPtr #include "nsDebug.h" // for NS_ASSERTION #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc -#include "nsPoint.h" // for nsIntPoint -#include "nsRect.h" // for nsIntRect #include "nsString.h" // for nsAutoCString namespace mozilla { @@ -82,7 +80,7 @@ ImageLayerComposite::GetLayer() } void -ImageLayerComposite::RenderLayer(const nsIntRect& aClipRect) +ImageLayerComposite::RenderLayer(const IntRect& aClipRect) { if (!mImageHost || !mImageHost->IsAttached()) { return; diff --git a/gfx/layers/composite/ImageLayerComposite.h b/gfx/layers/composite/ImageLayerComposite.h index 1cb0499a6fbe..850dc52fea8c 100644 --- a/gfx/layers/composite/ImageLayerComposite.h +++ b/gfx/layers/composite/ImageLayerComposite.h @@ -9,6 +9,7 @@ #include "GLTextureImage.h" // for TextureImage #include "ImageLayers.h" // for ImageLayer #include "mozilla/Attributes.h" // for override +#include "mozilla/gfx/Rect.h" #include "mozilla/RefPtr.h" // for RefPtr #include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite, etc #include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc @@ -16,9 +17,6 @@ #include "nscore.h" // for nsACString #include "CompositableHost.h" // for CompositableHost -struct nsIntPoint; -struct nsIntRect; - namespace mozilla { namespace layers { @@ -54,7 +52,7 @@ public: } } - virtual void RenderLayer(const nsIntRect& aClipRect) override; + virtual void RenderLayer(const gfx::IntRect& aClipRect) override; virtual void ComputeEffectiveTransforms(const mozilla::gfx::Matrix4x4& aTransformToSurface) override; diff --git a/gfx/layers/composite/PaintedLayerComposite.cpp b/gfx/layers/composite/PaintedLayerComposite.cpp index 076efd0d9a7a..20f79e0bcb57 100644 --- a/gfx/layers/composite/PaintedLayerComposite.cpp +++ b/gfx/layers/composite/PaintedLayerComposite.cpp @@ -22,9 +22,6 @@ #include "nsRefPtr.h" // for nsRefPtr #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc #include "nsMathUtils.h" // for NS_lround -#include "nsPoint.h" // for nsIntPoint -#include "nsRect.h" // for nsIntRect -#include "nsSize.h" // for nsIntSize #include "nsString.h" // for nsAutoCString #include "TextRenderer.h" #include "GeckoProfiler.h" @@ -114,7 +111,7 @@ PaintedLayerComposite::GetRenderState() } void -PaintedLayerComposite::RenderLayer(const nsIntRect& aClipRect) +PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect) { if (!mBuffer || !mBuffer->IsAttached()) { return; diff --git a/gfx/layers/composite/PaintedLayerComposite.h b/gfx/layers/composite/PaintedLayerComposite.h index 564ea4e8fc6c..911f99945723 100644 --- a/gfx/layers/composite/PaintedLayerComposite.h +++ b/gfx/layers/composite/PaintedLayerComposite.h @@ -7,7 +7,7 @@ #define GFX_PaintedLayerComposite_H #include "Layers.h" // for Layer (ptr only), etc -#include "gfxRect.h" // for gfxRect +#include "mozilla/gfx/Rect.h" #include "mozilla/Attributes.h" // for override #include "mozilla/RefPtr.h" // for RefPtr #include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite, etc @@ -16,9 +16,6 @@ #include "nsRegion.h" // for nsIntRegion #include "nscore.h" // for nsACString -struct nsIntPoint; -struct nsIntRect; - namespace mozilla { namespace layers { @@ -57,7 +54,7 @@ public: virtual TiledLayerComposer* GetTiledLayerComposer() override; - virtual void RenderLayer(const nsIntRect& aClipRect) override; + virtual void RenderLayer(const gfx::IntRect& aClipRect) override; virtual void CleanupResources() override; diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index 66bff22a0511..d685f38f8b87 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -58,8 +58,6 @@ #define RECYCLE_LOG(...) do { } while (0) #endif -struct nsIntPoint; - namespace mozilla { namespace layers { diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index ec8e639a1e02..c734a64a121f 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -28,9 +28,9 @@ #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc #include "nscore.h" // for nsACString #include "mozilla/layers/AtomicRefCountedWithFinalize.h" +#include "mozilla/gfx/Rect.h" class gfxReusableSurfaceWrapper; -struct nsIntRect; namespace mozilla { namespace gl { @@ -70,7 +70,7 @@ class BigImageIterator public: virtual void BeginBigImageIteration() = 0; virtual void EndBigImageIteration() {}; - virtual nsIntRect GetTileRect() = 0; + virtual gfx::IntRect GetTileRect() = 0; virtual size_t GetTileCount() = 0; virtual bool NextTile() = 0; }; diff --git a/gfx/layers/composite/TiledContentHost.cpp b/gfx/layers/composite/TiledContentHost.cpp index 70883ccad581..c21e94c7fe79 100644 --- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -13,9 +13,9 @@ #include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL #include "nsAString.h" #include "nsDebug.h" // for NS_WARNING -#include "nsPoint.h" // for nsIntPoint +#include "nsPoint.h" // for IntPoint #include "nsPrintfCString.h" // for nsPrintfCString -#include "nsRect.h" // for nsIntRect +#include "nsRect.h" // for IntRect #include "nsSize.h" // for nsIntSize #include "mozilla/layers/TiledContentClient.h" @@ -171,7 +171,7 @@ TiledLayerBufferComposite::Upload() TileHost TiledLayerBufferComposite::ValidateTile(TileHost aTile, - const nsIntPoint& aTileOrigin, + const IntPoint& aTileOrigin, const nsIntRegion& aDirtyRect) { if (aTile.IsPlaceholderTile()) { @@ -465,7 +465,7 @@ TiledContentHost::RenderTile(const TileHost& aTile, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, const nsIntRegion& aScreenRegion, - const nsIntPoint& aTextureOffset, + const IntPoint& aTextureOffset, const nsIntSize& aTextureBounds) { if (aTile.IsPlaceholderTile()) { @@ -477,7 +477,7 @@ TiledContentHost::RenderTile(const TileHost& aTile, if (aBackgroundColor) { aEffectChain.mPrimaryEffect = new EffectSolidColor(ToColor(*aBackgroundColor)); nsIntRegionRectIterator it(aScreenRegion); - for (const nsIntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { + for (const IntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, 1.0, aTransform); } @@ -507,7 +507,7 @@ TiledContentHost::RenderTile(const TileHost& aTile, aEffectChain.mPrimaryEffect = effect; nsIntRegionRectIterator it(aScreenRegion); - for (const nsIntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { + for (const IntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); Rect textureRect(rect->x - aTextureOffset.x, rect->y - aTextureOffset.y, rect->width, rect->height); @@ -574,7 +574,7 @@ TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, uint32_t rowCount = 0; uint32_t tileX = 0; - nsIntRect visibleRect = aVisibleRegion.GetBounds(); + IntRect visibleRect = aVisibleRegion.GetBounds(); gfx::IntSize scaledTileSize = aLayerBuffer.GetScaledTileSize(); for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { rowCount++; @@ -592,17 +592,17 @@ TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, } TileHost tileTexture = aLayerBuffer. - GetTile(nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width), - aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height))); + GetTile(IntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width), + aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height))); if (tileTexture != aLayerBuffer.GetPlaceholderTile()) { nsIntRegion tileDrawRegion; - tileDrawRegion.And(nsIntRect(x, y, w, h), aLayerBuffer.GetValidRegion()); + tileDrawRegion.And(IntRect(x, y, w, h), aLayerBuffer.GetValidRegion()); tileDrawRegion.And(tileDrawRegion, aVisibleRegion); tileDrawRegion.Sub(tileDrawRegion, maskRegion); if (!tileDrawRegion.IsEmpty()) { tileDrawRegion.ScaleRoundOut(resolution, resolution); - nsIntPoint tileOffset((x - tileStartX) * resolution, + IntPoint tileOffset((x - tileStartX) * resolution, (y - tileStartY) * resolution); gfx::IntSize tileSize = aLayerBuffer.GetTileSize(); RenderTile(tileTexture, aBackgroundColor, aEffectChain, aOpacity, aTransform, diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index f765a063a8f5..6281aa9e3a89 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -32,8 +32,6 @@ #endif class gfxReusableSurfaceWrapper; -struct nsIntPoint; -struct nsIntRect; namespace mozilla { namespace gfx { @@ -164,7 +162,7 @@ public: protected: TileHost ValidateTile(TileHost aTile, - const nsIntPoint& aTileRect, + const gfx::IntPoint& aTileRect, const nsIntRegion& dirtyRect); // do nothing, the desctructor in the texture host takes care of releasing resources @@ -291,7 +289,7 @@ private: const gfx::Filter& aFilter, const gfx::Rect& aClipRect, const nsIntRegion& aScreenRegion, - const nsIntPoint& aTextureOffset, + const gfx::IntPoint& aTextureOffset, const gfx::IntSize& aTextureBounds); void EnsureTileStore() {} diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 6b19cf62436f..52d43ead6bc7 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -1076,7 +1076,7 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, UINT offset = 0; mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset); - nsIntRect intRect = nsIntRect(nsIntPoint(0, 0), mSize); + nsIntRect intRect = IntRect(IntPoint(0, 0), mSize); // Sometimes the invalid region is larger than we want to draw. nsIntRegion invalidRegionSafe; diff --git a/gfx/layers/d3d9/DeviceManagerD3D9.cpp b/gfx/layers/d3d9/DeviceManagerD3D9.cpp index 75750e68ca24..a978d10bad16 100644 --- a/gfx/layers/d3d9/DeviceManagerD3D9.cpp +++ b/gfx/layers/d3d9/DeviceManagerD3D9.cpp @@ -132,7 +132,7 @@ SwapChainD3D9::PrepareForRendering() } void -SwapChainD3D9::Present(const nsIntRect &aRect) +SwapChainD3D9::Present(const gfx::IntRect &aRect) { RECT r; r.left = aRect.x; diff --git a/gfx/layers/d3d9/DeviceManagerD3D9.h b/gfx/layers/d3d9/DeviceManagerD3D9.h index a29f96d7980b..18419aba22e4 100644 --- a/gfx/layers/d3d9/DeviceManagerD3D9.h +++ b/gfx/layers/d3d9/DeviceManagerD3D9.h @@ -12,8 +12,7 @@ #include "nsTArray.h" #include "mozilla/layers/CompositorTypes.h" #include "mozilla/RefPtr.h" - -struct nsIntRect; +#include "mozilla/gfx/Rect.h" namespace mozilla { namespace layers { @@ -102,7 +101,7 @@ public: * This function will present the selected rectangle of the swap chain to * its associated window. */ - void Present(const nsIntRect &aRect); + void Present(const gfx::IntRect &aRect); void Present(); private: diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index 65a1b5718ac6..e630f22b9141 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -554,7 +554,7 @@ DataTextureSourceD3D9::GetTileRect(uint32_t aTileIndex) const nsIntRect DataTextureSourceD3D9::GetTileRect() { - return ThebesIntRect(GetTileRect(mCurrentTile)); + return GetTileRect(mCurrentTile); } CairoTextureClientD3D9::CairoTextureClientD3D9(ISurfaceAllocator* aAllocator, diff --git a/gfx/layers/ipc/CompositableForwarder.h b/gfx/layers/ipc/CompositableForwarder.h index 69992b2a7989..3f08962b94cf 100644 --- a/gfx/layers/ipc/CompositableForwarder.h +++ b/gfx/layers/ipc/CompositableForwarder.h @@ -15,9 +15,7 @@ #include "mozilla/layers/LayersTypes.h" // for LayersBackend #include "mozilla/layers/TextureClient.h" // for TextureClient #include "nsRegion.h" // for nsIntRegion - -struct nsIntPoint; -struct nsIntRect; +#include "mozilla/gfx/Rect.h" namespace mozilla { namespace layers { @@ -79,7 +77,7 @@ public: * Communicate the picture rect of a YUV image in aLayer to the compositor */ virtual void UpdatePictureRect(CompositableClient* aCompositable, - const nsIntRect& aRect) = 0; + const gfx::IntRect& aRect) = 0; #ifdef MOZ_WIDGET_GONK virtual void UseOverlaySource(CompositableClient* aCompositabl, diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index fc072bd34f2f..83bb6420831d 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -27,6 +27,7 @@ #include "mozilla/DebugOnly.h" // for DebugOnly #include "mozilla/gfx/2D.h" // for DrawTarget #include "mozilla/gfx/Point.h" // for IntSize +#include "mozilla/gfx/Rect.h" // for IntSize #include "mozilla/ipc/Transport.h" // for Transport #include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager #include "mozilla/layers/APZThreadUtils.h" // for APZCTreeManager @@ -48,7 +49,6 @@ #include "nsDebug.h" // for NS_ASSERTION, etc #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc #include "nsIWidget.h" // for nsIWidget -#include "nsRect.h" // for nsIntRect #include "nsTArray.h" // for nsTArray #include "nsThreadUtils.h" // for NS_IsMainThread #include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop @@ -606,7 +606,7 @@ CompositorParent::RecvResume() bool CompositorParent::RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot, - const nsIntRect& aRect) + const gfx::IntRect& aRect) { RefPtr target = GetDrawTargetForDescriptor(aInSnapshot, gfx::BackendType::CAIRO); ForceComposeToTarget(target, &aRect); @@ -977,7 +977,7 @@ CompositorParent::SetShadowProperties(Layer* aLayer) } void -CompositorParent::CompositeToTarget(DrawTarget* aTarget, const nsIntRect* aRect) +CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect) { profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START); PROFILER_LABEL("CompositorParent", "Composite", @@ -1072,7 +1072,7 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const nsIntRect* aRect) } void -CompositorParent::ForceComposeToTarget(DrawTarget* aTarget, const nsIntRect* aRect) +CompositorParent::ForceComposeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect) { PROFILER_LABEL("CompositorParent", "ForceComposeToTarget", js::ProfileEntry::Category::GRAPHICS); @@ -1141,14 +1141,6 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, mRootLayerTreeID, aPaintSequenceNumber); } -#ifdef DEBUG - if (aTransactionId <= mPendingTransaction) { - // Logging added to help diagnose why we're triggering the assert below. - // See bug 1145295 - printf_stderr("CRASH: aTransactionId %" PRIu64 " <= mPendingTransaction %" PRIu64 "\n", - aTransactionId, mPendingTransaction); - } -#endif MOZ_ASSERT(aTransactionId > mPendingTransaction); mPendingTransaction = aTransactionId; @@ -1346,7 +1338,7 @@ CompositorParent::AllocPLayerTransactionParent(const nsTArray& aB // mWidget doesn't belong to the compositor thread, so it should be set to // nullptr before returning from this method, to avoid accessing it elsewhere. - nsIntRect rect; + gfx::IntRect rect; mWidget->GetClientBounds(rect); InitializeLayerManager(aBackendHints); mWidget = nullptr; @@ -1608,7 +1600,7 @@ public: virtual bool RecvNotifyChildCreated(const uint64_t& child) override; virtual bool RecvAdoptChild(const uint64_t& child) override { return false; } virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot, - const nsIntRect& aRect) override + const gfx::IntRect& aRect) override { return true; } virtual bool RecvFlushRendering() override { return true; } virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) override { return true; } diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index e066ec29e7b4..e673d014b43f 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -167,7 +167,7 @@ public: virtual bool RecvNotifyChildCreated(const uint64_t& child) override; virtual bool RecvAdoptChild(const uint64_t& child) override; virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot, - const nsIntRect& aRect) override; + const gfx::IntRect& aRect) override; virtual bool RecvFlushRendering() override; virtual bool RecvGetTileSize(int32_t* aWidth, int32_t* aHeight) override; @@ -364,8 +364,8 @@ protected: virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) override; virtual void ScheduleTask(CancelableTask*, int); void CompositeCallback(TimeStamp aScheduleTime); - void CompositeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect = nullptr); - void ForceComposeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect = nullptr); + void CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr); + void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr); void SetEGLSurfaceSize(int width, int height); diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 33a02465eac5..fa048ea55e05 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -38,8 +38,6 @@ #include "mozilla/StaticPtr.h" // for StaticRefPtr #include "mozilla/layers/TextureClient.h" -struct nsIntRect; - namespace mozilla { namespace ipc { class Shmem; @@ -149,7 +147,7 @@ ImageBridgeChild::UseOverlaySource(CompositableClient* aCompositable, void ImageBridgeChild::UpdatePictureRect(CompositableClient* aCompositable, - const nsIntRect& aRect) + const gfx::IntRect& aRect) { MOZ_ASSERT(aCompositable); MOZ_ASSERT(aCompositable->GetIPDLActor()); diff --git a/gfx/layers/ipc/ImageBridgeChild.h b/gfx/layers/ipc/ImageBridgeChild.h index a2339b8f5171..39fec3bd6772 100644 --- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -17,10 +17,9 @@ #include "mozilla/layers/PImageBridgeChild.h" #include "nsDebug.h" // for NS_RUNTIMEABORT #include "nsRegion.h" // for nsIntRegion +#include "mozilla/gfx/Rect.h" class MessageLoop; -struct nsIntPoint; -struct nsIntRect; namespace base { class Thread; @@ -241,7 +240,7 @@ public: * Communicate the picture rect of a YUV image in aLayer to the compositor */ virtual void UpdatePictureRect(CompositableClient* aCompositable, - const nsIntRect& aRect) override; + const gfx::IntRect& aRect) override; virtual void UpdateTextureRegion(CompositableClient* aCompositable, diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 6fc1bd53b74e..f94a4426b75a 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -19,9 +19,9 @@ include "ImageLayers.h"; using mozilla::GraphicsFilterType from "mozilla/GfxMessageUtils.h"; using struct gfxRGBA from "gfxColor.h"; using struct mozilla::gfx::Point3D from "mozilla/gfx/Point.h"; +using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h"; using class mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h"; using nscoord from "nsCoord.h"; -using struct nsIntPoint from "nsPoint.h"; using struct nsRect from "nsRect.h"; using struct nsPoint from "nsPoint.h"; using class mozilla::TimeDuration from "mozilla/TimeStamp.h"; @@ -47,7 +47,7 @@ namespace mozilla { namespace layers { struct TargetConfig { - nsIntRect naturalBounds; + IntRect naturalBounds; ScreenRotation rotation; ScreenOrientation orientation; nsIntRegion clearRegion; @@ -72,8 +72,8 @@ struct OpAttachAsyncCompositable { }; struct ThebesBufferData { - nsIntRect rect; - nsIntPoint rotation; + IntRect rect; + IntPoint rotation; }; struct CubicBezierFunction { @@ -195,7 +195,7 @@ struct Animation { // Change a layer's attributes struct CommonLayerAttributes { - nsIntRect layerBounds; + IntRect layerBounds; nsIntRegion visibleRegion; EventRegions eventRegions; TransformMatrix transform; @@ -241,8 +241,8 @@ struct ContainerLayerAttributes { // cross process at some point by passing the HMDConfig uint64_t hmdInfo; }; -struct ColorLayerAttributes { LayerColor color; nsIntRect bounds; }; -struct CanvasLayerAttributes { GraphicsFilterType filter; nsIntRect bounds; }; +struct ColorLayerAttributes { LayerColor color; IntRect bounds; }; +struct CanvasLayerAttributes { GraphicsFilterType filter; IntRect bounds; }; struct RefLayerAttributes { int64_t id; // TODO: Once bug 1132895 is fixed we shouldn't need to propagate the override @@ -269,8 +269,8 @@ struct LayerAttributes { // See nsIWidget Configurations struct PluginWindowData { uintptr_t windowId; - nsIntRect[] clip; - nsIntRect bounds; + IntRect[] clip; + IntRect bounds; bool visible; }; @@ -348,7 +348,7 @@ struct OpPaintTextureRegion { struct OpUpdatePictureRect { PCompositable compositable; - nsIntRect picture; + IntRect picture; }; /** diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index 6a3dd2931491..0ef312d736a6 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ using struct gfxPoint from "gfxPoint.h"; -using struct nsIntRect from "nsRect.h"; using nsIntRegion from "nsRegion.h"; using struct mozilla::layers::MagicGrallocBufferHandle from "gfxipc/ShadowLayerUtils.h"; using struct mozilla::layers::GrallocBufferRef from "gfxipc/ShadowLayerUtils.h"; @@ -11,6 +10,7 @@ using struct mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h"; using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h"; +using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h"; using mozilla::gfx::IntSize from "mozilla/gfx/Point.h"; using gfxImageFormat from "gfxTypes.h"; diff --git a/gfx/layers/ipc/PCompositor.ipdl b/gfx/layers/ipc/PCompositor.ipdl index 312e2cbee932..ba3620506bec 100644 --- a/gfx/layers/ipc/PCompositor.ipdl +++ b/gfx/layers/ipc/PCompositor.ipdl @@ -60,7 +60,7 @@ child: * application on the widgets. Used on Windows and Linux in managing * plugin widgets. */ - async UpdatePluginConfigurations(nsIntPoint aContentOffset, + async UpdatePluginConfigurations(IntPoint aContentOffset, nsIntRegion aVisibleRegion, PluginWindowData[] aPlugins); @@ -95,7 +95,7 @@ parent: // // NB: this message will result in animations, transforms, effects, // and so forth being interpolated. That's what we want to happen. - sync MakeSnapshot(SurfaceDescriptor inSnapshot, nsIntRect dirtyRect); + sync MakeSnapshot(SurfaceDescriptor inSnapshot, IntRect dirtyRect); // Make sure any pending composites are started immediately and // block until they are completed. diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index f320f533cbb6..43ce9f925378 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -28,14 +28,11 @@ #include "mozilla/layers/TextureClient.h" // for TextureClient #include "mozilla/mozalloc.h" // for operator new, etc #include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc -#include "nsRect.h" // for nsIntRect #include "nsSize.h" // for nsIntSize #include "nsTArray.h" // for nsAutoTArray, nsTArray, etc #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc #include "mozilla/ReentrantMonitor.h" -struct nsIntPoint; - namespace mozilla { namespace ipc { class Shmem; @@ -62,7 +59,7 @@ public: , mRotationChanged(false) {} - void Begin(const nsIntRect& aTargetBounds, ScreenRotation aRotation, + void Begin(const gfx::IntRect& aTargetBounds, ScreenRotation aRotation, dom::ScreenOrientation aOrientation) { mOpen = true; @@ -139,7 +136,7 @@ public: EditVector mCset; EditVector mPaints; ShadowableLayerSet mMutants; - nsIntRect mTargetBounds; + gfx::IntRect mTargetBounds; ScreenRotation mTargetRotation; dom::ScreenOrientation mTargetOrientation; bool mSwapRequired; @@ -185,7 +182,7 @@ ShadowLayerForwarder::~ShadowLayerForwarder() } void -ShadowLayerForwarder::BeginTransaction(const nsIntRect& aTargetBounds, +ShadowLayerForwarder::BeginTransaction(const gfx::IntRect& aTargetBounds, ScreenRotation aRotation, dom::ScreenOrientation aOrientation) { @@ -354,7 +351,7 @@ ShadowLayerForwarder::UpdateTextureRegion(CompositableClient* aCompositable, void ShadowLayerForwarder::UpdatePictureRect(CompositableClient* aCompositable, - const nsIntRect& aRect) + const gfx::IntRect& aRect) { MOZ_ASSERT(aCompositable); MOZ_ASSERT(aCompositable->GetIPDLActor()); diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index 17758dca1c2f..81cf4bd34e78 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -12,6 +12,7 @@ #include // for uint64_t #include "gfxTypes.h" #include "mozilla/Attributes.h" // for override +#include "mozilla/gfx/Rect.h" #include "mozilla/WidgetUtils.h" // for ScreenRotation #include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc @@ -22,9 +23,6 @@ #include "nsTArrayForwardDeclare.h" // for InfallibleTArray #include "nsIWidget.h" -struct nsIntPoint; -struct nsIntRect; - namespace mozilla { namespace layers { @@ -170,7 +168,7 @@ public: * Begin recording a transaction to be forwarded atomically to a * LayerManagerComposite. */ - void BeginTransaction(const nsIntRect& aTargetBounds, + void BeginTransaction(const gfx::IntRect& aTargetBounds, ScreenRotation aRotation, mozilla::dom::ScreenOrientation aOrientation); @@ -258,7 +256,7 @@ public: * Communicate the picture rect of an image to the compositor */ void UpdatePictureRect(CompositableClient* aCompositable, - const nsIntRect& aRect) override; + const gfx::IntRect& aRect) override; /** * See CompositableForwarder::UseTexture diff --git a/gfx/layers/opengl/GLBlitTextureImageHelper.cpp b/gfx/layers/opengl/GLBlitTextureImageHelper.cpp index d1ea27e64cc6..43ac3c80e0c2 100644 --- a/gfx/layers/opengl/GLBlitTextureImageHelper.cpp +++ b/gfx/layers/opengl/GLBlitTextureImageHelper.cpp @@ -37,8 +37,8 @@ GLBlitTextureImageHelper::~GLBlitTextureImageHelper() } void -GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect, - TextureImage *aDst, const nsIntRect& aDstRect) +GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const gfx::IntRect& aSrcRect, + TextureImage *aDst, const gfx::IntRect& aDstRect) { GLContext *gl = mCompositor->gl(); NS_ASSERTION(!aSrc->InUpdate(), "Source texture is in update!"); @@ -61,8 +61,8 @@ GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aDst->BeginBigImageIteration(); do { // calculate portion of the tile that is going to be painted to - nsIntRect dstSubRect; - nsIntRect dstTextureRect = ThebesIntRect(aDst->GetTileRect()); + gfx::IntRect dstSubRect; + gfx::IntRect dstTextureRect = aDst->GetTileRect(); dstSubRect.IntersectRect(aDstRect, dstTextureRect); // this tile is not part of the destination rectangle aDstRect @@ -70,7 +70,7 @@ GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const nsIntRect& continue; // (*) transform the rect of this tile into the rectangle defined by aSrcRect... - nsIntRect dstInSrcRect(dstSubRect); + gfx::IntRect dstInSrcRect(dstSubRect); dstInSrcRect.MoveBy(-aDstRect.TopLeft()); // ...which might be of different size, hence scale accordingly dstInSrcRect.ScaleRoundOut(1.0f / blitScaleX, 1.0f / blitScaleY); @@ -83,8 +83,8 @@ GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const nsIntRect& // now iterate over all tiles in the source Image... do { // calculate portion of the source tile that is in the source rect - nsIntRect srcSubRect; - nsIntRect srcTextureRect = ThebesIntRect(aSrc->GetTileRect()); + gfx::IntRect srcSubRect; + gfx::IntRect srcTextureRect = aSrc->GetTileRect(); srcSubRect.IntersectRect(aSrcRect, srcTextureRect); // this tile is not part of the source rect @@ -104,7 +104,7 @@ GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const nsIntRect& // and the desired destination rectange // in destination space. // We need to transform this back into destination space, inverting the transform from (*) - nsIntRect srcSubInDstRect(srcSubRect); + gfx::IntRect srcSubInDstRect(srcSubRect); srcSubInDstRect.MoveBy(-aSrcRect.TopLeft()); srcSubInDstRect.ScaleRoundOut(blitScaleX, blitScaleY); srcSubInDstRect.MoveBy(aDstRect.TopLeft()); diff --git a/gfx/layers/opengl/GLBlitTextureImageHelper.h b/gfx/layers/opengl/GLBlitTextureImageHelper.h index 9075a6f85f2f..1a0703145356 100644 --- a/gfx/layers/opengl/GLBlitTextureImageHelper.h +++ b/gfx/layers/opengl/GLBlitTextureImageHelper.h @@ -10,8 +10,7 @@ #include "mozilla/Attributes.h" #include "GLContextTypes.h" #include "GLConsts.h" - -struct nsIntRect; +#include "mozilla/gfx/Rect.h" namespace mozilla { namespace gl { @@ -62,8 +61,8 @@ public: * - active texture (will be 0) * - texture 0 binding */ - void BlitTextureImage(gl::TextureImage *aSrc, const nsIntRect& aSrcRect, - gl::TextureImage *aDst, const nsIntRect& aDstRect); + void BlitTextureImage(gl::TextureImage *aSrc, const gfx::IntRect& aSrcRect, + gl::TextureImage *aDst, const gfx::IntRect& aDstRect); }; } diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h index 63c5002e6330..a284a9a9399c 100644 --- a/gfx/layers/opengl/OGLShaderProgram.h +++ b/gfx/layers/opengl/OGLShaderProgram.h @@ -21,7 +21,6 @@ #include struct gfxRGBA; -struct nsIntRect; namespace mozilla { namespace layers { diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index 1ca62a491f4a..ea426107214b 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -22,7 +22,6 @@ #include "mozilla/layers/ISurfaceAllocator.h" #include "mozilla/layers/YCbCrImageDataSerializer.h" #include "mozilla/layers/GrallocTextureHost.h" -#include "nsPoint.h" // for nsIntPoint #include "nsRegion.h" // for nsIntRegion #include "AndroidSurfaceTexture.h" #include "GfxTexturesReporter.h" // for GfxTexturesReporter @@ -258,7 +257,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, if (aDestRegion && !aSrcOffset && - !aDestRegion->IsEqual(nsIntRect(0, 0, size.width, size.height))) { + !aDestRegion->IsEqual(gfx::IntRect(0, 0, size.width, size.height))) { // UpdateFromDataSource will ignore our specified aDestRegion since the texture // hasn't been allocated with glTexImage2D yet. Call Resize() to force the // allocation (full size, but no upload), and then we'll only upload the pixels @@ -292,9 +291,9 @@ TextureImageTextureSourceOGL::EnsureBuffer(const nsIntSize& aSize, } void -TextureImageTextureSourceOGL::CopyTo(const nsIntRect& aSourceRect, +TextureImageTextureSourceOGL::CopyTo(const gfx::IntRect& aSourceRect, DataTextureSource *aDest, - const nsIntRect& aDestRect) + const gfx::IntRect& aDestRect) { MOZ_ASSERT(aDest->AsSourceOGL(), "Incompatible destination type!"); TextureImageTextureSourceOGL *dest = @@ -341,9 +340,9 @@ TextureImageTextureSourceOGL::GetFormat() const return gfx::SurfaceFormat::UNKNOWN; } -nsIntRect TextureImageTextureSourceOGL::GetTileRect() +gfx::IntRect TextureImageTextureSourceOGL::GetTileRect() { - return ThebesIntRect(mTexImage->GetTileRect()); + return mTexImage->GetTileRect(); } void diff --git a/gfx/layers/opengl/TextureHostOGL.h b/gfx/layers/opengl/TextureHostOGL.h index c4b5bfe3c9d1..1859178ca4c3 100644 --- a/gfx/layers/opengl/TextureHostOGL.h +++ b/gfx/layers/opengl/TextureHostOGL.h @@ -39,8 +39,6 @@ class gfxReusableSurfaceWrapper; class nsIntRegion; -struct nsIntPoint; -struct nsIntRect; namespace mozilla { namespace gfx { @@ -204,9 +202,9 @@ public: void EnsureBuffer(const gfx::IntSize& aSize, gfxContentType aContentType); - void CopyTo(const nsIntRect& aSourceRect, - DataTextureSource* aDest, - const nsIntRect& aDestRect); + void CopyTo(const gfx::IntRect& aSourceRect, + DataTextureSource* aDest, + const gfx::IntRect& aDestRect); virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() override { return this; } @@ -250,7 +248,7 @@ public: mIterating = false; } - virtual nsIntRect GetTileRect() override; + virtual gfx::IntRect GetTileRect() override; virtual size_t GetTileCount() override { diff --git a/gfx/src/FilterSupport.cpp b/gfx/src/FilterSupport.cpp index 18174a3888af..88f5f34c50a1 100644 --- a/gfx/src/FilterSupport.cpp +++ b/gfx/src/FilterSupport.cpp @@ -1300,7 +1300,7 @@ ResultChangeRegionForPrimitive(const FilterPrimitiveDescription& aDescription, } case PrimitiveType::Tile: - return ThebesIntRect(aDescription.PrimitiveSubregion()); + return aDescription.PrimitiveSubregion(); case PrimitiveType::ConvolveMatrix: { @@ -1384,7 +1384,7 @@ FilterSupport::ComputeResultChangeRegion(const FilterDescription& aFilter, } nsIntRegion changeRegion = ResultChangeRegionForPrimitive(descr, inputChangeRegions); - changeRegion.And(changeRegion, ThebesIntRect(descr.PrimitiveSubregion())); + changeRegion.And(changeRegion, descr.PrimitiveSubregion()); resultChangeRegions.AppendElement(changeRegion); } @@ -1459,7 +1459,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a region.Or(region, aInputExtents[1]); } if (coefficients[3] > 0.0f) { - region = ThebesIntRect(aDescription.PrimitiveSubregion()); + region = aDescription.PrimitiveSubregion(); } return region; } @@ -1474,7 +1474,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a if (atts.GetColor(eFloodColor).a == 0.0f) { return nsIntRect(); } - return ThebesIntRect(aDescription.PrimitiveSubregion()); + return aDescription.PrimitiveSubregion(); } case PrimitiveType::ColorMatrix: @@ -1482,7 +1482,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a if (atts.GetUint(eColorMatrixType) == (uint32_t)SVG_FECOLORMATRIX_TYPE_MATRIX) { const nsTArray& values = atts.GetFloats(eColorMatrixValues); if (values.Length() == 20 && values[19] > 0.0f) { - return ThebesIntRect(aDescription.PrimitiveSubregion()); + return aDescription.PrimitiveSubregion(); } } return aInputExtents[0]; @@ -1493,7 +1493,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a AttributeMap functionAttributes = atts.GetAttributeMap(eComponentTransferFunctionA); if (ResultOfZeroUnderTransferFunction(functionAttributes) > 0.0f) { - return ThebesIntRect(aDescription.PrimitiveSubregion()); + return aDescription.PrimitiveSubregion(); } return aInputExtents[0]; } @@ -1501,7 +1501,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a case PrimitiveType::Turbulence: case PrimitiveType::Image: { - return ThebesIntRect(aDescription.PrimitiveSubregion()); + return aDescription.PrimitiveSubregion(); } case PrimitiveType::Morphology: @@ -1530,7 +1530,7 @@ FilterSupport::ComputePostFilterExtents(const FilterDescription& aFilter, for (int32_t i = 0; i < int32_t(primitives.Length()); ++i) { const FilterPrimitiveDescription& descr = primitives[i]; - nsIntRegion filterSpace = ThebesIntRect(descr.FilterSpaceBounds()); + nsIntRegion filterSpace = descr.FilterSpaceBounds(); nsTArray inputExtents; for (size_t j = 0; j < descr.NumberOfInputs(); j++) { @@ -1542,7 +1542,7 @@ FilterSupport::ComputePostFilterExtents(const FilterDescription& aFilter, inputExtents.AppendElement(inputExtent); } nsIntRegion extent = PostFilterExtentsForPrimitive(descr, inputExtents); - extent.And(extent, ThebesIntRect(descr.PrimitiveSubregion())); + extent.And(extent, descr.PrimitiveSubregion()); postFilterExtents.AppendElement(extent); } @@ -1664,7 +1664,7 @@ FilterSupport::ComputeSourceNeededRegions(const FilterDescription& aFilter, for (int32_t i = primitives.Length() - 1; i >= 0; --i) { const FilterPrimitiveDescription& descr = primitives[i]; nsIntRegion neededRegion = primitiveNeededRegions[i]; - neededRegion.And(neededRegion, ThebesIntRect(descr.PrimitiveSubregion())); + neededRegion.And(neededRegion, descr.PrimitiveSubregion()); for (size_t j = 0; j < descr.NumberOfInputs(); j++) { int32_t inputIndex = descr.InputPrimitiveIndex(j); @@ -1682,7 +1682,7 @@ FilterSupport::ComputeSourceNeededRegions(const FilterDescription& aFilter, if (primitives.Length() > 0) { const FilterPrimitiveDescription& firstDescr = primitives[0]; aSourceGraphicNeededRegion.And(aSourceGraphicNeededRegion, - ThebesIntRect(firstDescr.FilterSpaceBounds())); + firstDescr.FilterSpaceBounds()); } } diff --git a/gfx/src/nsPoint.h b/gfx/src/nsPoint.h index 4a621d4ceda7..88dacf6c448e 100644 --- a/gfx/src/nsPoint.h +++ b/gfx/src/nsPoint.h @@ -10,8 +10,12 @@ #include "mozilla/gfx/BaseSize.h" #include "mozilla/gfx/BasePoint.h" #include "nsSize.h" +#include "mozilla/gfx/Point.h" -struct nsIntPoint; +// nsIntPoint represents a point in one of the types of pixels. +// Uses of nsIntPoint should eventually be converted to CSSIntPoint, +// LayoutDeviceIntPoint, etc. (see layout/base/Units.h). +typedef mozilla::gfx::IntPoint nsIntPoint; // nsPoint represents a point in app units. @@ -35,19 +39,7 @@ struct nsPoint : public mozilla::gfx::BasePoint { ScaleToOtherAppUnits(int32_t aFromAPP, int32_t aToAPP) const; }; -// nsIntPoint represents a point in one of the types of pixels. -// Uses of nsIntPoint should eventually be converted to CSSIntPoint, -// LayoutDeviceIntPoint, etc. (see layout/base/Units.h). - -struct nsIntPoint : public mozilla::gfx::BasePoint { - typedef mozilla::gfx::BasePoint Super; - - nsIntPoint() : Super() {} - nsIntPoint(const nsIntPoint& aPoint) : Super(aPoint) {} - nsIntPoint(int32_t aX, int32_t aY) : Super(aX, aY) {} - - inline nsPoint ToAppUnits(nscoord aAppUnitsPerPixel) const; -}; +inline nsPoint ToAppUnits(const nsIntPoint& aPoint, nscoord aAppUnitsPerPixel); inline nsIntPoint nsPoint::ScaleToNearestPixels(float aXScale, float aYScale, @@ -78,10 +70,10 @@ nsPoint::ScaleToOtherAppUnits(int32_t aFromAPP, int32_t aToAPP) const // app units are integer multiples of pixels, so no rounding needed inline nsPoint -nsIntPoint::ToAppUnits(nscoord aAppUnitsPerPixel) const +ToAppUnits(const nsIntPoint& aPoint, nscoord aAppUnitsPerPixel) { - return nsPoint(NSIntPixelsToAppUnits(x, aAppUnitsPerPixel), - NSIntPixelsToAppUnits(y, aAppUnitsPerPixel)); + return nsPoint(NSIntPixelsToAppUnits(aPoint.x, aAppUnitsPerPixel), + NSIntPixelsToAppUnits(aPoint.y, aAppUnitsPerPixel)); } #endif /* NSPOINT_H */ diff --git a/gfx/src/nsRect.cpp b/gfx/src/nsRect.cpp index 41a031503942..d1a3dd63914b 100644 --- a/gfx/src/nsRect.cpp +++ b/gfx/src/nsRect.cpp @@ -15,6 +15,20 @@ static_assert((int(NS_SIDE_TOP) == 0) && (int(NS_SIDE_LEFT) == 3), "The mozilla::css::Side sequence must match the nsMargin nscoord sequence"); +nsRect +ToAppUnits(const nsIntRect& aRect, nscoord aAppUnitsPerPixel) +{ + return nsRect(NSIntPixelsToAppUnits(aRect.x, aAppUnitsPerPixel), + NSIntPixelsToAppUnits(aRect.y, aAppUnitsPerPixel), + NSIntPixelsToAppUnits(aRect.width, aAppUnitsPerPixel), + NSIntPixelsToAppUnits(aRect.height, aAppUnitsPerPixel)); +} + +const nsIntRect& GetMaxSizedIntRect() { + static const nsIntRect r(0, 0, INT32_MAX, INT32_MAX); + return r; +} + #ifdef DEBUG // Diagnostics diff --git a/gfx/src/nsRect.h b/gfx/src/nsRect.h index e424cefd1daa..c840386dc247 100644 --- a/gfx/src/nsRect.h +++ b/gfx/src/nsRect.h @@ -13,18 +13,18 @@ #include "nsDebug.h" // for NS_WARNING #include "gfxCore.h" // for NS_GFX #include "mozilla/Likely.h" // for MOZ_UNLIKELY -#include "mozilla/gfx/BaseRect.h" // for BaseRect -#include "mozilla/gfx/NumericTools.h" // for RoundUpToMultiple, RoundDownToMultiple +#include "mozilla/gfx/Rect.h" #include "nsCoord.h" // for nscoord, etc #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc #include "nsPoint.h" // for nsIntPoint, nsPoint #include "nsSize.h" // for nsIntSize, nsSize #include "nscore.h" // for NS_BUILD_REFCNT_LOGGING -struct nsIntRect; struct nsMargin; struct nsIntMargin; +typedef mozilla::gfx::IntRect nsIntRect; + struct NS_GFX nsRect : public mozilla::gfx::BaseRect { typedef mozilla::gfx::BaseRect Super; @@ -179,56 +179,6 @@ struct NS_GFX nsRect : } }; -struct NS_GFX nsIntRect : - public mozilla::gfx::BaseRect { - typedef mozilla::gfx::BaseRect Super; - - // Constructors - nsIntRect() : Super() - { - } - nsIntRect(const nsIntRect& aRect) : Super(aRect) - { - } - nsIntRect(const nsIntPoint& aOrigin, const nsIntSize &aSize) : Super(aOrigin, aSize) - { - } - nsIntRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) : - Super(aX, aY, aWidth, aHeight) - { - } - - MOZ_WARN_UNUSED_RESULT inline nsRect - ToAppUnits(nscoord aAppUnitsPerPixel) const; - - // Returns a special nsIntRect that's used in some places to signify - // "all available space". - static const nsIntRect& GetMaxSizedIntRect() { - static const nsIntRect r(0, 0, INT32_MAX, INT32_MAX); - return r; - } - - void InflateToMultiple(const nsIntSize& aTileSize) - { - int32_t xMost = XMost(); - int32_t yMost = YMost(); - - x = RoundDownToMultiple(x, aTileSize.width); - y = RoundDownToMultiple(y, aTileSize.height); - xMost = RoundUpToMultiple(xMost, aTileSize.width); - yMost = RoundUpToMultiple(yMost, aTileSize.height); - - width = xMost - x; - height = yMost - y; - } - - // This is here only to keep IPDL-generated code happy. DO NOT USE. - bool operator==(const nsIntRect& aRect) const - { - return IsEqualEdges(aRect); - } -}; - /* * App Unit/Pixel conversions */ @@ -335,15 +285,11 @@ nsRect::ToInsidePixels(nscoord aAppUnitsPerPixel) const return ScaleToInsidePixels(1.0f, 1.0f, aAppUnitsPerPixel); } +const nsIntRect& GetMaxSizedIntRect(); + // app units are integer multiples of pixels, so no rounding needed -inline nsRect -nsIntRect::ToAppUnits(nscoord aAppUnitsPerPixel) const -{ - return nsRect(NSIntPixelsToAppUnits(x, aAppUnitsPerPixel), - NSIntPixelsToAppUnits(y, aAppUnitsPerPixel), - NSIntPixelsToAppUnits(width, aAppUnitsPerPixel), - NSIntPixelsToAppUnits(height, aAppUnitsPerPixel)); -} +nsRect +ToAppUnits(const nsIntRect& aRect, nscoord aAppUnitsPerPixel); #ifdef DEBUG // Diagnostics diff --git a/gfx/src/nsRegion.h b/gfx/src/nsRegion.h index 632398d62eba..05dca175cac2 100644 --- a/gfx/src/nsRegion.h +++ b/gfx/src/nsRegion.h @@ -699,7 +699,7 @@ public: RectIterator rgnIter(*this); const Rect* currentRect; while ((currentRect = rgnIter.Next())) { - nsRect appRect = currentRect->ToAppUnits(aAppUnitsPerPixel); + nsRect appRect = ::ToAppUnits(*currentRect, aAppUnitsPerPixel); result.Or(result, appRect); } return result; diff --git a/gfx/thebes/gfx2DGlue.h b/gfx/thebes/gfx2DGlue.h index 8ed44c25d5e7..520c5409c9ae 100644 --- a/gfx/thebes/gfx2DGlue.h +++ b/gfx/thebes/gfx2DGlue.h @@ -38,11 +38,6 @@ inline Rect ToRect(const nsIntRect &aRect) return Rect(aRect.x, aRect.y, aRect.width, aRect.height); } -inline IntRect ToIntRect(const nsIntRect &aRect) -{ - return IntRect(aRect.x, aRect.y, aRect.width, aRect.height); -} - inline Color ToColor(const gfxRGBA &aRGBA) { return Color(Float(aRGBA.r), Float(aRGBA.g), @@ -71,9 +66,9 @@ inline Point ToPoint(const gfxPoint &aPoint) return Point(Float(aPoint.x), Float(aPoint.y)); } -inline IntPoint ToIntPoint(const nsIntPoint &aPoint) +inline IntMargin ToIntMargin(const nsIntMargin& aMargin) { - return IntPoint(aPoint.x, aPoint.y); + return IntMargin(aMargin.top, aMargin.right, aMargin.bottom, aMargin.left); } inline Size ToSize(const gfxSize &aSize) @@ -157,11 +152,6 @@ inline gfxRect ThebesRect(const Rect &aRect) return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height); } -inline nsIntRect ThebesIntRect(const IntRect &aRect) -{ - return nsIntRect(aRect.x, aRect.y, aRect.width, aRect.height); -} - inline gfxRGBA ThebesRGBA(const Color &aColor) { return gfxRGBA(aColor.r, aColor.g, aColor.b, aColor.a); diff --git a/gfx/thebes/gfxASurface.h b/gfx/thebes/gfxASurface.h index 42ffd44385f9..d61ee65adbd6 100644 --- a/gfx/thebes/gfxASurface.h +++ b/gfx/thebes/gfxASurface.h @@ -12,6 +12,7 @@ #include "gfxTypes.h" #include "nscore.h" #include "nsSize.h" +#include "mozilla/gfx/Rect.h" #ifdef MOZILLA_INTERNAL_API #include "nsStringFwd.h" @@ -20,8 +21,6 @@ #endif class gfxImageSurface; -struct nsIntPoint; -struct nsIntRect; struct gfxRect; struct gfxPoint; diff --git a/gfx/thebes/gfxAlphaRecovery.h b/gfx/thebes/gfxAlphaRecovery.h index 0122d9c83e22..9fed1681e954 100644 --- a/gfx/thebes/gfxAlphaRecovery.h +++ b/gfx/thebes/gfxAlphaRecovery.h @@ -8,9 +8,8 @@ #include "mozilla/SSE.h" #include "gfxTypes.h" -#include "nsRect.h" +#include "mozilla/gfx/Rect.h" -struct nsIntRect; class gfxImageSurface; class gfxAlphaRecovery { @@ -53,11 +52,11 @@ public: * * The returned rect is always a superset of |aRect|. */ - static nsIntRect AlignRectForSubimageRecovery(const nsIntRect& aRect, - gfxImageSurface* aSurface); + static mozilla::gfx::IntRect AlignRectForSubimageRecovery(const mozilla::gfx::IntRect& aRect, + gfxImageSurface* aSurface); #else - static nsIntRect AlignRectForSubimageRecovery(const nsIntRect& aRect, - gfxImageSurface*) + static mozilla::gfx::IntRect AlignRectForSubimageRecovery(const mozilla::gfx::IntRect& aRect, + gfxImageSurface*) { return aRect; } #endif diff --git a/gfx/thebes/gfxAlphaRecoverySSE2.cpp b/gfx/thebes/gfxAlphaRecoverySSE2.cpp index a395cee6b776..a65dc9a4458f 100644 --- a/gfx/thebes/gfxAlphaRecoverySSE2.cpp +++ b/gfx/thebes/gfxAlphaRecoverySSE2.cpp @@ -5,7 +5,6 @@ #include "gfxAlphaRecovery.h" #include "gfxImageSurface.h" -#include "nsRect.h" #include // This file should only be compiled on x86 and x64 systems. Additionally, @@ -137,8 +136,8 @@ ByteAlignment(int32_t aAlignToLog2, int32_t aX, int32_t aY=0, int32_t aStride=1) return (aX + aStride * aY) & ((1 << aAlignToLog2) - 1); } -/*static*/ nsIntRect -gfxAlphaRecovery::AlignRectForSubimageRecovery(const nsIntRect& aRect, +/*static*/ mozilla::gfx::IntRect +gfxAlphaRecovery::AlignRectForSubimageRecovery(const mozilla::gfx::IntRect& aRect, gfxImageSurface* aSurface) { NS_ASSERTION(gfxImageFormat::ARGB32 == aSurface->Format(), @@ -229,8 +228,8 @@ gfxAlphaRecovery::AlignRectForSubimageRecovery(const nsIntRect& aRect, return aRect; FOUND_SOLUTION: - nsIntRect solution = nsIntRect(x - dx, y - dy, w + dr + dx, h + dy); - MOZ_ASSERT(nsIntRect(0, 0, sw, surfaceSize.height).Contains(solution), + mozilla::gfx::IntRect solution = mozilla::gfx::IntRect(x - dx, y - dy, w + dr + dx, h + dy); + MOZ_ASSERT(mozilla::gfx::IntRect(0, 0, sw, surfaceSize.height).Contains(solution), "'Solution' extends outside surface bounds!"); return solution; } diff --git a/gfx/thebes/gfxD2DSurface.cpp b/gfx/thebes/gfxD2DSurface.cpp index 96f2a425f34a..6d37a7997ef2 100644 --- a/gfx/thebes/gfxD2DSurface.cpp +++ b/gfx/thebes/gfxD2DSurface.cpp @@ -57,7 +57,7 @@ gfxD2DSurface::Present() } void -gfxD2DSurface::Scroll(const nsIntPoint &aDelta, const nsIntRect &aClip) +gfxD2DSurface::Scroll(const nsIntPoint &aDelta, const mozilla::gfx::IntRect &aClip) { cairo_rectangle_t rect; rect.x = aClip.x; @@ -80,7 +80,7 @@ gfxD2DSurface::GetDC(bool aRetainContents) } void -gfxD2DSurface::ReleaseDC(const nsIntRect *aUpdatedRect) +gfxD2DSurface::ReleaseDC(const mozilla::gfx::IntRect *aUpdatedRect) { if (!aUpdatedRect) { return cairo_d2d_release_dc(CairoSurface(), nullptr); diff --git a/gfx/thebes/gfxD2DSurface.h b/gfx/thebes/gfxD2DSurface.h index 10687e640328..fccb25cbb168 100644 --- a/gfx/thebes/gfxD2DSurface.h +++ b/gfx/thebes/gfxD2DSurface.h @@ -12,7 +12,6 @@ #include struct ID3D10Texture2D; -struct nsIntRect; class gfxD2DSurface : public gfxASurface { public: @@ -32,14 +31,14 @@ public: virtual ~gfxD2DSurface(); void Present(); - void Scroll(const nsIntPoint &aDelta, const nsIntRect &aClip); + void Scroll(const nsIntPoint &aDelta, const mozilla::gfx::IntRect &aClip); - virtual const gfxIntSize GetSize() const; + virtual const mozilla::gfx::IntSize GetSize() const; ID3D10Texture2D *GetTexture(); HDC GetDC(bool aRetainContents); - void ReleaseDC(const nsIntRect *aUpdatedRect); + void ReleaseDC(const mozilla::gfx::IntRect *aUpdatedRect); }; #endif /* GFX_D2DSURFACE_H */ diff --git a/gfx/thebes/gfxQtNativeRenderer.h b/gfx/thebes/gfxQtNativeRenderer.h index da11d9f1c153..393ce4a710c6 100644 --- a/gfx/thebes/gfxQtNativeRenderer.h +++ b/gfx/thebes/gfxQtNativeRenderer.h @@ -9,9 +9,9 @@ #include "gfxColor.h" #include "gfxContext.h" #include "gfxXlibSurface.h" +#include "mozilla/gfx/Rect.h" class QRect; -struct nsIntRect; /** * This class lets us take code that draws into an Xlib surface drawable and lets us @@ -31,8 +31,9 @@ public: */ virtual nsresult DrawWithXlib(cairo_surface_t* surface, nsIntPoint offset, - nsIntRect* clipRects, uint32_t numClipRects) = 0; - + mozilla::gfx::IntRect* clipRects, + uint32_t numClipRects) = 0; + enum { // If set, then Draw() is opaque, i.e., every pixel in the intersection // of the clipRect and (offset.x,offset.y,bounds.width,bounds.height) diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index a38d8437490d..a45df24fdfd6 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -690,7 +690,7 @@ PathFromRegionInternal(gfxContext* aContext, const nsIntRegion& aRegion) { aContext->NewPath(); nsIntRegionRectIterator iter(aRegion); - const nsIntRect* r; + const IntRect* r; while ((r = iter.Next()) != nullptr) { aContext->Rectangle(gfxRect(r->x, r->y, r->width, r->height)); } @@ -709,7 +709,7 @@ PathFromRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion) RefPtr pb = aTarget->CreatePathBuilder(); nsIntRegionRectIterator iter(aRegion); - const nsIntRect* r; + const IntRect* r; while ((r = iter.Next()) != nullptr) { pb->MoveTo(Point(r->x, r->y)); pb->LineTo(Point(r->XMost(), r->y)); @@ -725,7 +725,7 @@ static void ClipToRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion) { if (!aRegion.IsComplex()) { - nsIntRect rect = aRegion.GetBounds(); + IntRect rect = aRegion.GetBounds(); aTarget->PushClipRect(Rect(rect.x, rect.y, rect.width, rect.height)); return; } @@ -847,9 +847,9 @@ gfxUtils::TransformRectToRect(const gfxRect& aFrom, const IntPoint& aToTopLeft, * to ints then convert those ints back to doubles to make sure that * they equal the doubles that we got in. */ bool -gfxUtils::GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut) +gfxUtils::GfxRectToIntRect(const gfxRect& aIn, IntRect* aOut) { - *aOut = nsIntRect(int32_t(aIn.X()), int32_t(aIn.Y()), + *aOut = IntRect(int32_t(aIn.X()), int32_t(aIn.Y()), int32_t(aIn.Width()), int32_t(aIn.Height())); return gfxRect(aOut->x, aOut->y, aOut->width, aOut->height).IsEqualEdges(aIn); } @@ -995,7 +995,7 @@ gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrData& aData, } /* static */ void gfxUtils::ClearThebesSurface(gfxASurface* aSurface, - nsIntRect* aRect, + IntRect* aRect, const gfxRGBA& aColor) { if (aSurface->CairoStatus()) { @@ -1008,11 +1008,11 @@ gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrData& aData, cairo_t* ctx = cairo_create(surf); cairo_set_source_rgba(ctx, aColor.r, aColor.g, aColor.b, aColor.a); cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE); - nsIntRect bounds; + IntRect bounds; if (aRect) { bounds = *aRect; } else { - bounds = nsIntRect(nsIntPoint(0, 0), aSurface->GetSize()); + bounds = IntRect(nsIntPoint(0, 0), aSurface->GetSize()); } cairo_rectangle(ctx, bounds.x, bounds.y, bounds.width, bounds.height); cairo_fill(ctx); diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index d3d06c6856f6..908b7908bc28 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -14,14 +14,13 @@ #include "mozilla/RefPtr.h" #include "nsColor.h" #include "nsPrintfCString.h" +#include "mozilla/gfx/Rect.h" class gfxASurface; class gfxDrawable; class nsIntRegion; class nsIPresShell; -struct nsIntRect; - namespace mozilla { namespace layers { struct PlanarYCbCrData; @@ -121,11 +120,11 @@ public: const IntPoint& aToBottomRight); /** - * If aIn can be represented exactly using an nsIntRect (i.e. + * If aIn can be represented exactly using an gfx::IntRect (i.e. * integer-aligned edges and coordinates in the int32_t range) then we * set aOut to that rectangle, otherwise return failure. */ - static bool GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut); + static bool GfxRectToIntRect(const gfxRect& aIn, mozilla::gfx::IntRect* aOut); /** * Return the smallest power of kScaleResolution (2) greater than or equal to @@ -163,7 +162,7 @@ public: * Clears surface to aColor (which defaults to transparent black). */ static void ClearThebesSurface(gfxASurface* aSurface, - nsIntRect* aRect = nullptr, + mozilla::gfx::IntRect* aRect = nullptr, const gfxRGBA& aColor = gfxRGBA(0.0, 0.0, 0.0, 0.0)); /** diff --git a/gfx/thebes/gfxXlibNativeRenderer.cpp b/gfx/thebes/gfxXlibNativeRenderer.cpp index 5dc8a723ae0c..c7f6cec50aeb 100644 --- a/gfx/thebes/gfxXlibNativeRenderer.cpp +++ b/gfx/thebes/gfxXlibNativeRenderer.cpp @@ -69,9 +69,9 @@ _convert_coord_to_int (double coord, int32_t *v) static bool _get_rectangular_clip (cairo_t *cr, - const nsIntRect& bounds, + const IntRect& bounds, bool *need_clip, - nsIntRect *rectangles, int max_rectangles, + IntRect *rectangles, int max_rectangles, int *num_rectangles) { cairo_rectangle_list_t *cliplist; @@ -90,8 +90,8 @@ _get_rectangular_clip (cairo_t *cr, clips = cliplist->rectangles; for (i = 0; i < cliplist->num_rectangles; ++i) { - - nsIntRect rect; + + IntRect rect; if (!_convert_coord_to_int (clips[i].x, &rect.x) || !_convert_coord_to_int (clips[i].y, &rect.y) || !_convert_coord_to_int (clips[i].width, &rect.width) || @@ -106,7 +106,7 @@ _get_rectangular_clip (cairo_t *cr, /* the bounds are entirely inside the clip region so we don't need to clip. */ *need_clip = false; goto FINISH; - } + } NS_ASSERTION(bounds.Contains(rect), "Was expecting to be clipped to bounds"); @@ -176,7 +176,7 @@ gfxXlibNativeRenderer::DrawCairo(cairo_t* cr, nsIntSize size, NS_ASSERTION(int32_t(device_offset_x) == device_offset_x && int32_t(device_offset_y) == device_offset_y, "Expected integer device offsets"); - nsIntPoint offset(NS_lroundf(matrix.x0 + device_offset_x), + IntPoint offset(NS_lroundf(matrix.x0 + device_offset_x), NS_lroundf(matrix.y0 + device_offset_y)); int max_rectangles = 0; @@ -189,14 +189,14 @@ gfxXlibNativeRenderer::DrawCairo(cairo_t* cr, nsIntSize size, /* The client won't draw outside the surface so consider this when analysing clip rectangles. */ - nsIntRect bounds(offset, size); + IntRect bounds(offset, size); bounds.IntersectRect(bounds, - nsIntRect(0, 0, + IntRect(0, 0, cairo_xlib_surface_get_width(target), cairo_xlib_surface_get_height(target))); bool needs_clip = true; - nsIntRect rectangles[MAX_STATIC_CLIP_RECTANGLES]; + IntRect rectangles[MAX_STATIC_CLIP_RECTANGLES]; int rect_count = 0; /* Check that the clip is rectangular and aligned on unit boundaries. */ @@ -360,7 +360,7 @@ CreateTempXlibSurface (cairo_surface_t* cairoTarget, } else { target_format = gfxXlibSurface::FindRenderFormat(dpy, imageFormat); - } + } } if (supportsAlternateVisual && @@ -436,7 +436,7 @@ CreateTempXlibSurface (cairo_surface_t* cairoTarget, bool gfxXlibNativeRenderer::DrawOntoTempSurface(cairo_surface_t *tempXlibSurface, - nsIntPoint offset) + IntPoint offset) { cairo_surface_flush(tempXlibSurface); /* no clipping is needed because the callback can't draw outside the native @@ -506,7 +506,7 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size, return; } - nsIntRect drawingRect(nsIntPoint(0, 0), size); + IntRect drawingRect(IntPoint(0, 0), size); // Drawing need only be performed within the clip extents // (and padding for the filter). if (!matrixIsIntegerTranslation) { @@ -516,7 +516,7 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size, } clipExtents.RoundOut(); - nsIntRect intExtents(int32_t(clipExtents.X()), + IntRect intExtents(int32_t(clipExtents.X()), int32_t(clipExtents.Y()), int32_t(clipExtents.Width()), int32_t(clipExtents.Height())); diff --git a/gfx/thebes/gfxXlibNativeRenderer.h b/gfx/thebes/gfxXlibNativeRenderer.h index e355fe62e451..4c3a08ef4e4c 100644 --- a/gfx/thebes/gfxXlibNativeRenderer.h +++ b/gfx/thebes/gfxXlibNativeRenderer.h @@ -8,6 +8,8 @@ #include "nsPoint.h" #include "nsRect.h" +#include "mozilla/gfx/Rect.h" +#include "mozilla/gfx/Point.h" #include namespace mozilla { @@ -18,8 +20,6 @@ namespace gfx { class gfxASurface; class gfxContext; -struct nsIntRect; -struct nsIntPoint; typedef struct _cairo cairo_t; typedef struct _cairo_surface cairo_surface_t; @@ -45,8 +45,9 @@ public: * no clipping is required. */ virtual nsresult DrawWithXlib(cairo_surface_t* surface, - nsIntPoint offset, - nsIntRect* clipRects, uint32_t numClipRects) = 0; + mozilla::gfx::IntPoint offset, + mozilla::gfx::IntRect* clipRects, + uint32_t numClipRects) = 0; enum { // If set, then Draw() is opaque, i.e., every pixel in the intersection @@ -93,11 +94,11 @@ private: void DrawFallback(mozilla::gfx::DrawTarget* dt, gfxContext* ctx, gfxASurface* aSurface, mozilla::gfx::IntSize& size, - nsIntRect& drawingRect, bool canDrawOverBackground, + mozilla::gfx::IntRect& drawingRect, bool canDrawOverBackground, uint32_t flags, Screen* screen, Visual* visual); bool DrawOntoTempSurface(cairo_surface_t *tempXlibSurface, - nsIntPoint offset); + mozilla::gfx::IntPoint offset); }; diff --git a/hal/sandbox/PHal.ipdl b/hal/sandbox/PHal.ipdl index f45d232ed249..829fc6421939 100644 --- a/hal/sandbox/PHal.ipdl +++ b/hal/sandbox/PHal.ipdl @@ -16,7 +16,7 @@ using mozilla::hal::WakeLockControl from "mozilla/HalTypes.h"; using mozilla::hal::SwitchState from "mozilla/HalTypes.h"; using mozilla::hal::SwitchDevice from "mozilla/HalTypes.h"; using mozilla::hal::ProcessPriority from "mozilla/HalTypes.h"; -using struct nsIntRect from "nsRect.h"; +using nsIntRect from "nsRect.h"; using PRTime from "prtime.h"; using mozilla::hal::FMRadioCountry from "mozilla/HalTypes.h"; using mozilla::hal::FMRadioOperation from "mozilla/HalTypes.h"; diff --git a/image/src/Decoder.cpp b/image/src/Decoder.cpp index d1bcdd8befb8..31e3adf5fb1f 100644 --- a/image/src/Decoder.cpp +++ b/image/src/Decoder.cpp @@ -628,7 +628,7 @@ Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */, // here when the first frame is complete. if (!mSendPartialInvalidations && !mIsAnimated) { mInvalidRect.UnionRect(mInvalidRect, - nsIntRect(nsIntPoint(0, 0), GetSize())); + gfx::IntRect(gfx::IntPoint(0, 0), GetSize())); } } diff --git a/image/src/ImageOps.h b/image/src/ImageOps.h index 86e84921f04d..fd3a6536d4e2 100644 --- a/image/src/ImageOps.h +++ b/image/src/ImageOps.h @@ -8,10 +8,10 @@ #define mozilla_image_src_ImageOps_h #include "nsCOMPtr.h" +#include "nsRect.h" class gfxDrawable; class imgIContainer; -struct nsIntRect; namespace mozilla { namespace image { diff --git a/image/src/MultipartImage.cpp b/image/src/MultipartImage.cpp index 766beb096ada..ddfb6b7d5ab7 100644 --- a/image/src/MultipartImage.cpp +++ b/image/src/MultipartImage.cpp @@ -182,7 +182,7 @@ void MultipartImage::FinishTransition() // Finally, send all the notifications for the new current part and send a // FRAME_UPDATE notification so that observers know to redraw. mTracker->SyncNotifyProgress(newCurrentPartTracker->GetProgress(), - nsIntRect::GetMaxSizedIntRect()); + GetMaxSizedIntRect()); } already_AddRefed diff --git a/image/src/ProgressTracker.cpp b/image/src/ProgressTracker.cpp index a9baace18852..bc74730c8dac 100644 --- a/image/src/ProgressTracker.cpp +++ b/image/src/ProgressTracker.cpp @@ -393,7 +393,7 @@ ProgressTracker::SyncNotify(IProgressObserver* aObserver) if (NS_FAILED(mImage->GetWidth(&rect.width)) || NS_FAILED(mImage->GetHeight(&rect.height))) { // Either the image has no intrinsic size, or it has an error. - rect = nsIntRect::GetMaxSizedIntRect(); + rect = GetMaxSizedIntRect(); } } diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index 370558a30c23..194283af7284 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -122,7 +122,7 @@ class ScaleRunner : public nsRunnable public: ScaleRunner(RasterImage* aImage, uint32_t aImageFlags, - const nsIntSize& aSize, + const IntSize& aSize, RawAccessFrameRef&& aSrcRef) : mImage(aImage) , mSrcRef(Move(aSrcRef)) @@ -235,7 +235,7 @@ private: WeakPtr mImage; RawAccessFrameRef mSrcRef; RawAccessFrameRef mDstRef; - const nsIntSize mDstSize; + const IntSize mDstSize; uint32_t mImageFlags; ScaleState mState; }; @@ -504,7 +504,7 @@ RasterImage::LookupFrameInternal(uint32_t aFrameNum, DrawableFrameRef RasterImage::LookupFrame(uint32_t aFrameNum, - const nsIntSize& aSize, + const IntSize& aSize, uint32_t aFlags) { MOZ_ASSERT(NS_IsMainThread()); @@ -568,7 +568,7 @@ RasterImage::GetRequestedFrameIndex(uint32_t aWhichFrame) const return aWhichFrame == FRAME_FIRST ? 0 : GetCurrentFrameIndex(); } -nsIntRect +IntRect RasterImage::GetFirstFrameRect() { if (mAnim) { @@ -576,7 +576,7 @@ RasterImage::GetFirstFrameRect() } // Fall back to our size. This is implicitly zero-size if !mHasSize. - return nsIntRect(nsIntPoint(0,0), mSize); + return IntRect(IntPoint(0,0), mSize); } NS_IMETHODIMP_(bool) @@ -702,7 +702,7 @@ RasterImage::CopyFrame(uint32_t aWhichFrame, uint32_t aFlags) return nullptr; } - nsIntRect intFrameRect = frameRef->GetRect(); + IntRect intFrameRect = frameRef->GetRect(); Rect rect(intFrameRect.x, intFrameRect.y, intFrameRect.width, intFrameRect.height); if (frameRef->IsSinglePixel()) { @@ -761,7 +761,7 @@ RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags) // If this frame covers the entire image, we can just reuse its existing // surface. RefPtr frameSurf; - nsIntRect frameRect = frameRef->GetRect(); + IntRect frameRect = frameRef->GetRect(); if (frameRect.x == 0 && frameRect.y == 0 && frameRect.width == mSize.width && frameRect.height == mSize.height) { @@ -905,7 +905,7 @@ class OnAddedFrameRunnable : public nsRunnable public: OnAddedFrameRunnable(RasterImage* aImage, uint32_t aNewFrameCount, - const nsIntRect& aNewRefreshArea) + const IntRect& aNewRefreshArea) : mImage(aImage) , mNewFrameCount(aNewFrameCount) , mNewRefreshArea(aNewRefreshArea) @@ -922,12 +922,12 @@ public: private: nsRefPtr mImage; uint32_t mNewFrameCount; - nsIntRect mNewRefreshArea; + IntRect mNewRefreshArea; }; void RasterImage::OnAddedFrame(uint32_t aNewFrameCount, - const nsIntRect& aNewRefreshArea) + const IntRect& aNewRefreshArea) { if (!NS_IsMainThread()) { nsCOMPtr runnable = @@ -1147,8 +1147,8 @@ RasterImage::SetLoopCount(int32_t aLoopCount) } } -NS_IMETHODIMP_(nsIntRect) -RasterImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect) +NS_IMETHODIMP_(IntRect) +RasterImage::GetImageSpaceInvalidationRect(const IntRect& aRect) { return aRect; } @@ -1333,7 +1333,7 @@ RasterImage::CanDiscard() { // Sets up a decoder for this image. already_AddRefed -RasterImage::CreateDecoder(const Maybe& aSize, uint32_t aFlags) +RasterImage::CreateDecoder(const Maybe& aSize, uint32_t aFlags) { // Make sure we actually get size before doing a full decode. if (aSize) { @@ -1472,7 +1472,7 @@ RasterImage::StartDecoding() } NS_IMETHODIMP -RasterImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) +RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags) { MOZ_ASSERT(NS_IsMainThread()); @@ -1487,7 +1487,7 @@ RasterImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) // Fall back to our intrinsic size if we don't support // downscale-during-decode. - nsIntSize targetSize = mDownscaleDuringDecode ? aSize : mSize; + IntSize targetSize = mDownscaleDuringDecode ? aSize : mSize; // Decide whether to sync decode images we can decode quickly. Here we are // explicitly trading off flashing for responsiveness in the case that we're @@ -1507,7 +1507,7 @@ RasterImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) } NS_IMETHODIMP -RasterImage::Decode(const Maybe& aSize, uint32_t aFlags) +RasterImage::Decode(const Maybe& aSize, uint32_t aFlags) { MOZ_ASSERT(!aSize || NS_IsMainThread()); @@ -1570,7 +1570,7 @@ RasterImage::Decode(const Maybe& aSize, uint32_t aFlags) } void -RasterImage::RecoverFromLossOfFrames(const nsIntSize& aSize, uint32_t aFlags) +RasterImage::RecoverFromLossOfFrames(const IntSize& aSize, uint32_t aFlags) { if (!mHasSize) { return; @@ -1595,7 +1595,7 @@ RasterImage::RecoverFromLossOfFrames(const nsIntSize& aSize, uint32_t aFlags) bool RasterImage::CanScale(GraphicsFilter aFilter, - const nsIntSize& aSize, + const IntSize& aSize, uint32_t aFlags) { #ifndef MOZ_ENABLE_SKIA @@ -1655,7 +1655,7 @@ RasterImage::CanScale(GraphicsFilter aFilter, } bool -RasterImage::CanDownscaleDuringDecode(const nsIntSize& aSize, uint32_t aFlags) +RasterImage::CanDownscaleDuringDecode(const IntSize& aSize, uint32_t aFlags) { // Check basic requirements: downscale-during-decode is enabled for this // image, we have all the source data and know our size, the flags allow us to @@ -1693,13 +1693,13 @@ RasterImage::NotifyNewScaledFrame() { // Send an invalidation so observers will repaint and can take advantage of // the new scaled frame if possible. - NotifyProgress(NoProgress, nsIntRect(0, 0, mSize.width, mSize.height)); + NotifyProgress(NoProgress, IntRect(0, 0, mSize.width, mSize.height)); } void RasterImage::RequestScale(imgFrame* aFrame, uint32_t aFlags, - const nsIntSize& aSize) + const IntSize& aSize) { // We don't scale frames which aren't fully decoded. if (!aFrame->IsImageComplete()) { @@ -1732,7 +1732,7 @@ RasterImage::RequestScale(imgFrame* aFrame, DrawResult RasterImage::DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef, gfxContext* aContext, - const nsIntSize& aSize, + const IntSize& aSize, const ImageRegion& aRegion, GraphicsFilter aFilter, uint32_t aFlags) @@ -1798,14 +1798,14 @@ RasterImage::DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef, * in gfxGraphicsFilter aFilter, * [const] in gfxMatrix aUserSpaceToImageSpace, * [const] in gfxRect aFill, - * [const] in nsIntRect aSubimage, - * [const] in nsIntSize aViewportSize, + * [const] in IntRect aSubimage, + * [const] in IntSize aViewportSize, * [const] in SVGImageContext aSVGContext, * in uint32_t aWhichFrame, * in uint32_t aFlags); */ NS_IMETHODIMP_(DrawResult) RasterImage::Draw(gfxContext* aContext, - const nsIntSize& aSize, + const IntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, GraphicsFilter aFilter, @@ -2028,7 +2028,7 @@ RasterImage::GetFramesNotified(uint32_t* aFramesNotified) void RasterImage::NotifyProgress(Progress aProgress, - const nsIntRect& aInvalidRect /* = nsIntRect() */, + const IntRect& aInvalidRect /* = IntRect() */, uint32_t aFlags /* = DECODE_FLAGS_DEFAULT */) { MOZ_ASSERT(NS_IsMainThread()); @@ -2111,7 +2111,7 @@ RasterImage::Unwrap() return self.forget(); } -nsIntSize +IntSize RasterImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, GraphicsFilter aFilter, uint32_t aFlags) { @@ -2120,10 +2120,10 @@ RasterImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, "Unexpected destination size"); if (mSize.IsEmpty() || aDest.IsEmpty()) { - return nsIntSize(0, 0); + return IntSize(0, 0); } - nsIntSize destSize(ceil(aDest.width), ceil(aDest.height)); + IntSize destSize(ceil(aDest.width), ceil(aDest.height)); if (aFilter == GraphicsFilter::FILTER_GOOD && CanDownscaleDuringDecode(destSize, aFlags)) { diff --git a/image/src/SVGDocumentWrapper.cpp b/image/src/SVGDocumentWrapper.cpp index fa2ab130f716..f03c548f5385 100644 --- a/image/src/SVGDocumentWrapper.cpp +++ b/image/src/SVGDocumentWrapper.cpp @@ -85,7 +85,7 @@ SVGDocumentWrapper::UpdateViewportBounds(const nsIntSize& aViewportSize) // If the bounds have changed, we need to do a layout flush. if (currentBounds.Size() != aViewportSize) { - mViewer->SetBounds(nsIntRect(nsIntPoint(0, 0), aViewportSize)); + mViewer->SetBounds(IntRect(IntPoint(0, 0), aViewportSize)); FlushLayout(); } diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index 4372041db2a7..005fab0d7cd1 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -246,7 +246,7 @@ NS_IMPL_ISUPPORTS(SVGLoadEventListener, nsIDOMEventListener) class SVGDrawingCallback : public gfxDrawingCallback { public: SVGDrawingCallback(SVGDocumentWrapper* aSVGDocumentWrapper, - const nsIntRect& aViewport, + const IntRect& aViewport, const IntSize& aSize, uint32_t aImageFlags) : mSVGDocumentWrapper(aSVGDocumentWrapper) @@ -260,7 +260,7 @@ public: const gfxMatrix& aTransform); private: nsRefPtr mSVGDocumentWrapper; - const nsIntRect mViewport; + const IntRect mViewport; const IntSize mSize; uint32_t mImageFlags; }; @@ -539,12 +539,12 @@ VectorImage::SendInvalidationNotifications() if (mProgressTracker) { SurfaceCache::RemoveImage(ImageKey(this)); mProgressTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE, - nsIntRect::GetMaxSizedIntRect()); + GetMaxSizedIntRect()); } } -NS_IMETHODIMP_(nsIntRect) -VectorImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect) +NS_IMETHODIMP_(IntRect) +VectorImage::GetImageSpaceInvalidationRect(const IntRect& aRect) { return aRect; } @@ -854,7 +854,7 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams) nsRefPtr cb = new SVGDrawingCallback(mSVGDocumentWrapper, - nsIntRect(nsIntPoint(0, 0), aParams.viewportSize), + IntRect(IntPoint(0, 0), aParams.viewportSize), aParams.size, aParams.flags); @@ -916,7 +916,7 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams) // Send out an invalidation so that surfaces that are still in use get // re-locked. See the discussion of the UnlockSurfaces call above. mProgressTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE, - nsIntRect::GetMaxSizedIntRect()); + GetMaxSizedIntRect()); } @@ -1177,7 +1177,7 @@ VectorImage::OnSVGDocumentLoaded() FLAG_FRAME_COMPLETE | FLAG_DECODE_COMPLETE | FLAG_ONLOAD_UNBLOCKED, - nsIntRect::GetMaxSizedIntRect()); + GetMaxSizedIntRect()); } EvaluateAnimation(); diff --git a/image/src/imgFrame.cpp b/image/src/imgFrame.cpp index ff9d75a9bc09..2b8b9060e2cc 100644 --- a/image/src/imgFrame.cpp +++ b/image/src/imgFrame.cpp @@ -695,7 +695,7 @@ imgFrame::ImageUpdatedInternal(const nsIntRect& aUpdateRect) // clamp to bounds, in case someone sends a bogus updateRect (I'm looking at // you, gif decoder) - nsIntRect boundsRect(mOffset, nsIntSize(mSize.width, mSize.height)); + nsIntRect boundsRect(mOffset, mSize); mDecoded.IntersectRect(mDecoded, boundsRect); // If the image is now complete, wake up anyone who's waiting. @@ -728,7 +728,7 @@ imgFrame::Finish(Opacity aFrameOpacity /* = Opacity::SOME_TRANSPARENCY */, nsIntRect imgFrame::GetRect() const { - return nsIntRect(mOffset, nsIntSize(mSize.width, mSize.height)); + return gfx::IntRect(mOffset, mSize); } int32_t diff --git a/image/src/imgRequestProxy.cpp b/image/src/imgRequestProxy.cpp index cf46bade85ac..a2d80605d612 100644 --- a/image/src/imgRequestProxy.cpp +++ b/image/src/imgRequestProxy.cpp @@ -840,7 +840,7 @@ NotificationTypeToString(int32_t aType) } void -imgRequestProxy::Notify(int32_t aType, const nsIntRect* aRect) +imgRequestProxy::Notify(int32_t aType, const mozilla::gfx::IntRect* aRect) { MOZ_ASSERT(aType != imgINotificationObserver::LOAD_COMPLETE, "Should call OnLoadComplete"); diff --git a/image/src/imgRequestProxy.h b/image/src/imgRequestProxy.h index 67a605f54846..34305154434c 100644 --- a/image/src/imgRequestProxy.h +++ b/image/src/imgRequestProxy.h @@ -17,6 +17,7 @@ #include "nsAutoPtr.h" #include "nsThreadUtils.h" #include "mozilla/TimeStamp.h" +#include "mozilla/gfx/Rect.h" #include "imgRequest.h" #include "IProgressObserver.h" @@ -31,7 +32,6 @@ class imgINotificationObserver; class imgStatusNotifyRunnable; -struct nsIntRect; class ProxyBehaviour; namespace mozilla { @@ -98,7 +98,7 @@ public: // imgINotificationObserver methods: virtual void Notify(int32_t aType, - const nsIntRect* aRect = nullptr) override; + const mozilla::gfx::IntRect* aRect = nullptr) override; virtual void OnLoadComplete(bool aLastPart) override; // imgIOnloadBlocker methods: diff --git a/image/test/unit/xpcshell.ini b/image/test/unit/xpcshell.ini index c3332743410d..2739f533f1c8 100644 --- a/image/test/unit/xpcshell.ini +++ b/image/test/unit/xpcshell.ini @@ -41,7 +41,7 @@ skip-if = android_version == "18" [test_encoder_apng.js] [test_encoder_png.js] [test_imgtools.js] -# Bug 676968: test fails consistently on Android -fail-if = os == "android" +# Bug 676968: test fails consistently on Android; crashes on 4.3 (bug 1156452) +skip-if = os == "android" [test_moz_icon_uri.js] [test_private_channel.js] diff --git a/ipc/unixsocket/UnixSocket.cpp b/ipc/unixsocket/UnixSocket.cpp deleted file mode 100644 index 1e0df9284ddf..000000000000 --- a/ipc/unixsocket/UnixSocket.cpp +++ /dev/null @@ -1,667 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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 "UnixSocket.h" -#include "nsTArray.h" -#include "nsXULAppAPI.h" -#include -#include "mozilla/unused.h" - -static const size_t MAX_READ_SIZE = 1 << 16; - -namespace mozilla { -namespace ipc { - -// -// UnixSocketConsumerIO -// - -class UnixSocketConsumerIO final : public UnixSocketWatcher - , protected SocketIOBase -{ -public: - UnixSocketConsumerIO(MessageLoop* mIOLoop, - UnixSocketConsumer* aConsumer, - UnixSocketConnector* aConnector, - const nsACString& aAddress); - ~UnixSocketConsumerIO(); - - void GetSocketAddr(nsAString& aAddrStr) const; - SocketConsumerBase* GetConsumer(); - SocketBase* GetSocketBase(); - - // Shutdown state - // - - bool IsShutdownOnMainThread() const; - void ShutdownOnMainThread(); - - bool IsShutdownOnIOThread() const; - void ShutdownOnIOThread(); - - // Delayed-task handling - // - - void SetDelayedConnectTask(CancelableTask* aTask); - void ClearDelayedConnectTask(); - void CancelDelayedConnectTask(); - - // Task callback methods - // - - /** - * Run bind/listen to prepare for further runs of accept() - */ - void Listen(); - - /** - * Connect to a socket - */ - void Connect(); - - void Send(UnixSocketRawData* aData); - - // I/O callback methods - // - - void OnAccepted(int aFd, const sockaddr_any* aAddr, - socklen_t aAddrLen) override; - void OnConnected() override; - void OnError(const char* aFunction, int aErrno) override; - void OnListening() override; - void OnSocketCanReceiveWithoutBlocking() override; - void OnSocketCanSendWithoutBlocking() override; - -private: - void FireSocketError(); - - // Set up flags on file descriptor. - static bool SetSocketFlags(int aFd); - - /** - * Consumer pointer. Non-thread safe RefPtr, so should only be manipulated - * directly from main thread. All non-main-thread accesses should happen with - * mIO as container. - */ - RefPtr mConsumer; - - /** - * Connector object used to create the connection we are currently using. - */ - nsAutoPtr mConnector; - - /** - * If true, do not requeue whatever task we're running - */ - bool mShuttingDownOnIOThread; - - /** - * Address we are connecting to, assuming we are creating a client connection. - */ - nsCString mAddress; - - /** - * Size of the socket address struct - */ - socklen_t mAddrSize; - - /** - * Address struct of the socket currently in use - */ - sockaddr_any mAddr; - - /** - * Task member for delayed connect task. Should only be access on main thread. - */ - CancelableTask* mDelayedConnectTask; -}; - -UnixSocketConsumerIO::UnixSocketConsumerIO(MessageLoop* mIOLoop, - UnixSocketConsumer* aConsumer, - UnixSocketConnector* aConnector, - const nsACString& aAddress) - : UnixSocketWatcher(mIOLoop) - , SocketIOBase(MAX_READ_SIZE) - , mConsumer(aConsumer) - , mConnector(aConnector) - , mShuttingDownOnIOThread(false) - , mAddress(aAddress) - , mDelayedConnectTask(nullptr) -{ - MOZ_ASSERT(mConsumer); - MOZ_ASSERT(mConnector); -} - -UnixSocketConsumerIO::~UnixSocketConsumerIO() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(IsShutdownOnMainThread()); -} - -void -UnixSocketConsumerIO::GetSocketAddr(nsAString& aAddrStr) const -{ - if (!mConnector) { - NS_WARNING("No connector to get socket address from!"); - aAddrStr.Truncate(); - return; - } - mConnector->GetSocketAddr(mAddr, aAddrStr); -} - -SocketConsumerBase* -UnixSocketConsumerIO::GetConsumer() -{ - return mConsumer.get(); -} - -SocketBase* -UnixSocketConsumerIO::GetSocketBase() -{ - return GetConsumer(); -} - -bool -UnixSocketConsumerIO::IsShutdownOnMainThread() const -{ - MOZ_ASSERT(NS_IsMainThread()); - - return mConsumer == nullptr; -} - -void -UnixSocketConsumerIO::ShutdownOnMainThread() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!IsShutdownOnMainThread()); - - mConsumer = nullptr; -} - -bool -UnixSocketConsumerIO::IsShutdownOnIOThread() const -{ - return mShuttingDownOnIOThread; -} - -void -UnixSocketConsumerIO::ShutdownOnIOThread() -{ - MOZ_ASSERT(!NS_IsMainThread()); - MOZ_ASSERT(!mShuttingDownOnIOThread); - - Close(); // will also remove fd from I/O loop - mShuttingDownOnIOThread = true; -} - -void -UnixSocketConsumerIO::SetDelayedConnectTask(CancelableTask* aTask) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mDelayedConnectTask = aTask; -} - -void -UnixSocketConsumerIO::ClearDelayedConnectTask() -{ - MOZ_ASSERT(NS_IsMainThread()); - - mDelayedConnectTask = nullptr; -} - -void -UnixSocketConsumerIO::CancelDelayedConnectTask() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!mDelayedConnectTask) { - return; - } - - mDelayedConnectTask->Cancel(); - ClearDelayedConnectTask(); -} - -void -UnixSocketConsumerIO::Listen() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(mConnector); - - // This will set things we don't particularly care about, but it will hand - // back the correct structure size which is what we do care about. - if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) { - NS_WARNING("Cannot create socket address!"); - FireSocketError(); - return; - } - - if (!IsOpen()) { - int fd = mConnector->Create(); - if (fd < 0) { - NS_WARNING("Cannot create socket fd!"); - FireSocketError(); - return; - } - if (!SetSocketFlags(fd)) { - NS_WARNING("Cannot set socket flags!"); - FireSocketError(); - return; - } - SetFd(fd); - - // calls OnListening on success, or OnError otherwise - nsresult rv = UnixSocketWatcher::Listen( - reinterpret_cast(&mAddr), mAddrSize); - NS_WARN_IF(NS_FAILED(rv)); - } -} - -void -UnixSocketConsumerIO::Connect() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(mConnector); - - if (!IsOpen()) { - int fd = mConnector->Create(); - if (fd < 0) { - NS_WARNING("Cannot create socket fd!"); - FireSocketError(); - return; - } - if (!SetSocketFlags(fd)) { - NS_WARNING("Cannot set socket flags!"); - FireSocketError(); - return; - } - SetFd(fd); - } - - if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) { - NS_WARNING("Cannot create socket address!"); - FireSocketError(); - return; - } - - // calls OnConnected() on success, or OnError() otherwise - nsresult rv = UnixSocketWatcher::Connect( - reinterpret_cast(&mAddr), mAddrSize); - NS_WARN_IF(NS_FAILED(rv)); -} - -void -UnixSocketConsumerIO::Send(UnixSocketRawData* aData) -{ - EnqueueData(aData); - AddWatchers(WRITE_WATCHER, false); -} - -void -UnixSocketConsumerIO::OnAccepted(int aFd, - const sockaddr_any* aAddr, - socklen_t aAddrLen) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING); - MOZ_ASSERT(aAddr); - MOZ_ASSERT(aAddrLen > 0 && (size_t)aAddrLen <= sizeof(mAddr)); - - memcpy (&mAddr, aAddr, aAddrLen); - mAddrSize = aAddrLen; - - if (!mConnector->SetUp(aFd)) { - NS_WARNING("Could not set up socket!"); - return; - } - - RemoveWatchers(READ_WATCHER|WRITE_WATCHER); - Close(); - if (!SetSocketFlags(aFd)) { - return; - } - SetSocket(aFd, SOCKET_IS_CONNECTED); - - nsRefPtr r = - new SocketIOEventRunnable( - this, SocketIOEventRunnable::CONNECT_SUCCESS); - NS_DispatchToMainThread(r); - - AddWatchers(READ_WATCHER, true); - if (HasPendingData()) { - AddWatchers(WRITE_WATCHER, false); - } -} - -void -UnixSocketConsumerIO::OnConnected() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); - - if (!SetSocketFlags(GetFd())) { - NS_WARNING("Cannot set socket flags!"); - FireSocketError(); - return; - } - - if (!mConnector->SetUp(GetFd())) { - NS_WARNING("Could not set up socket!"); - FireSocketError(); - return; - } - - nsRefPtr r = - new SocketIOEventRunnable( - this, SocketIOEventRunnable::CONNECT_SUCCESS); - NS_DispatchToMainThread(r); - - AddWatchers(READ_WATCHER, true); - if (HasPendingData()) { - AddWatchers(WRITE_WATCHER, false); - } -} - -void -UnixSocketConsumerIO::OnListening() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING); - - if (!mConnector->SetUpListenSocket(GetFd())) { - NS_WARNING("Could not set up listen socket!"); - FireSocketError(); - return; - } - - AddWatchers(READ_WATCHER, true); -} - -void -UnixSocketConsumerIO::OnError(const char* aFunction, int aErrno) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - UnixFdWatcher::OnError(aFunction, aErrno); - FireSocketError(); -} - -void -UnixSocketConsumerIO::OnSocketCanReceiveWithoutBlocking() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984 - - ssize_t res = ReceiveData(GetFd(), this); - if (res < 0) { - /* I/O error */ - RemoveWatchers(READ_WATCHER|WRITE_WATCHER); - } else if (!res) { - /* EOF or peer shutdown */ - RemoveWatchers(READ_WATCHER); - } -} - -void -UnixSocketConsumerIO::OnSocketCanSendWithoutBlocking() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984 - - nsresult rv = SendPendingData(GetFd(), this); - if (NS_FAILED(rv)) { - return; - } - - if (HasPendingData()) { - AddWatchers(WRITE_WATCHER, false); - } -} - -void -UnixSocketConsumerIO::FireSocketError() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - // Clean up watchers, statuses, fds - Close(); - - // Tell the main thread we've errored - nsRefPtr r = - new SocketIOEventRunnable( - this, SocketIOEventRunnable::CONNECT_ERROR); - - NS_DispatchToMainThread(r); -} - -bool -UnixSocketConsumerIO::SetSocketFlags(int aFd) -{ - // Set socket addr to be reused even if kernel is still waiting to close - int n = 1; - if (setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) < 0) { - return false; - } - - // Set close-on-exec bit. - int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD)); - if (-1 == flags) { - return false; - } - flags |= FD_CLOEXEC; - if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) { - return false; - } - - // Set non-blocking status flag. - flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL)); - if (-1 == flags) { - return false; - } - flags |= O_NONBLOCK; - if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) { - return false; - } - - return true; -} - -// -// Socket tasks -// - -class ListenTask final : public SocketIOTask -{ -public: - ListenTask(UnixSocketConsumerIO* aIO) - : SocketIOTask(aIO) - { } - - void Run() override - { - MOZ_ASSERT(!NS_IsMainThread()); - - if (!IsCanceled()) { - GetIO()->Listen(); - } - } -}; - -class ConnectTask final : public SocketIOTask -{ -public: - ConnectTask(UnixSocketConsumerIO* aIO) - : SocketIOTask(aIO) - { } - - void Run() override - { - MOZ_ASSERT(!NS_IsMainThread()); - MOZ_ASSERT(!IsCanceled()); - - GetIO()->Connect(); - } -}; - -class DelayedConnectTask final : public SocketIOTask -{ -public: - DelayedConnectTask(UnixSocketConsumerIO* aIO) - : SocketIOTask(aIO) - { } - - void Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - if (IsCanceled()) { - return; - } - - UnixSocketConsumerIO* io = GetIO(); - if (io->IsShutdownOnMainThread()) { - return; - } - - io->ClearDelayedConnectTask(); - XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ConnectTask(io)); - } -}; - -// -// UnixSocketConsumer -// - -UnixSocketConsumer::UnixSocketConsumer() -: mIO(nullptr) -{ } - -UnixSocketConsumer::~UnixSocketConsumer() -{ - MOZ_ASSERT(!mIO); -} - -bool -UnixSocketConsumer::SendSocketData(UnixSocketRawData* aData) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (!mIO) { - return false; - } - - MOZ_ASSERT(!mIO->IsShutdownOnMainThread()); - XRE_GetIOMessageLoop()->PostTask( - FROM_HERE, - new SocketIOSendTask(mIO, aData)); - - return true; -} - -bool -UnixSocketConsumer::SendSocketData(const nsACString& aStr) -{ - if (aStr.Length() > MAX_READ_SIZE) { - return false; - } - - nsAutoPtr data( - new UnixSocketRawData(aStr.BeginReading(), aStr.Length())); - - if (!SendSocketData(data)) { - return false; - } - - unused << data.forget(); - - return true; -} - -void -UnixSocketConsumer::CloseSocket() -{ - MOZ_ASSERT(NS_IsMainThread()); - if (!mIO) { - return; - } - - mIO->CancelDelayedConnectTask(); - - // From this point on, we consider mIO as being deleted. - // We sever the relationship here so any future calls to listen or connect - // will create a new implementation. - mIO->ShutdownOnMainThread(); - - XRE_GetIOMessageLoop()->PostTask( - FROM_HERE, new SocketIOShutdownTask(mIO)); - - mIO = nullptr; - - NotifyDisconnect(); -} - -void -UnixSocketConsumer::GetSocketAddr(nsAString& aAddrStr) -{ - aAddrStr.Truncate(); - if (!mIO || GetConnectionStatus() != SOCKET_CONNECTED) { - NS_WARNING("No socket currently open!"); - return; - } - mIO->GetSocketAddr(aAddrStr); -} - -bool -UnixSocketConsumer::ConnectSocket(UnixSocketConnector* aConnector, - const char* aAddress, - int aDelayMs) -{ - MOZ_ASSERT(aConnector); - MOZ_ASSERT(NS_IsMainThread()); - - nsAutoPtr connector(aConnector); - - if (mIO) { - NS_WARNING("Socket already connecting/connected!"); - return false; - } - - nsCString addr(aAddress); - MessageLoop* ioLoop = XRE_GetIOMessageLoop(); - mIO = new UnixSocketConsumerIO(ioLoop, this, connector.forget(), addr); - SetConnectionStatus(SOCKET_CONNECTING); - if (aDelayMs > 0) { - DelayedConnectTask* connectTask = new DelayedConnectTask(mIO); - mIO->SetDelayedConnectTask(connectTask); - MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs); - } else { - ioLoop->PostTask(FROM_HERE, new ConnectTask(mIO)); - } - return true; -} - -bool -UnixSocketConsumer::ListenSocket(UnixSocketConnector* aConnector) -{ - MOZ_ASSERT(aConnector); - MOZ_ASSERT(NS_IsMainThread()); - - nsAutoPtr connector(aConnector); - - if (mIO) { - NS_WARNING("Socket already connecting/connected!"); - return false; - } - - mIO = new UnixSocketConsumerIO( - XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString()); - SetConnectionStatus(SOCKET_LISTENING); - XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ListenTask(mIO)); - return true; -} - -} // namespace ipc -} // namespace mozilla diff --git a/ipc/unixsocket/UnixSocket.h b/ipc/unixsocket/UnixSocket.h deleted file mode 100644 index 9867c796f8d4..000000000000 --- a/ipc/unixsocket/UnixSocket.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* 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_ipc_unixsocket_h -#define mozilla_ipc_unixsocket_h - -#include -#include "nsAutoPtr.h" -#include "nsString.h" -#include "nsThreadUtils.h" -#include "mozilla/ipc/SocketBase.h" -#include "mozilla/ipc/UnixSocketWatcher.h" -#include "mozilla/RefPtr.h" -#include "UnixSocketConnector.h" - -namespace mozilla { -namespace ipc { - -class UnixSocketConsumerIO; - -class UnixSocketConsumer : public SocketConsumerBase -{ -protected: - virtual ~UnixSocketConsumer(); - -public: - UnixSocketConsumer(); - - /** - * Queue data to be sent to the socket on the IO thread. Can only be called on - * originating thread. - * - * @param aMessage Data to be sent to socket - * - * @return true if data is queued, false otherwise (i.e. not connected) - */ - bool SendSocketData(UnixSocketRawData* aMessage); - - /** - * Convenience function for sending strings to the socket (common in bluetooth - * profile usage). Converts to a UnixSocketRawData struct. Can only be called - * on originating thread. - * - * @param aMessage String to be sent to socket - * - * @return true if data is queued, false otherwise (i.e. not connected) - */ - bool SendSocketData(const nsACString& aMessage); - - /** - * Starts a task on the socket that will try to connect to a socket in a - * non-blocking manner. - * - * @param aConnector Connector object for socket type specific functions - * @param aAddress Address to connect to. - * @param aDelayMs Time delay in milli-seconds. - * - * @return true on connect task started, false otherwise. - */ - bool ConnectSocket(UnixSocketConnector* aConnector, - const char* aAddress, - int aDelayMs = 0); - - /** - * Starts a task on the socket that will try to accept a new connection in a - * non-blocking manner. - * - * @param aConnector Connector object for socket type specific functions - * - * @return true on listen started, false otherwise - */ - bool ListenSocket(UnixSocketConnector* aConnector); - - /** - * Queues the internal representation of socket for deletion. Can be called - * from main thread. - */ - void CloseSocket(); - - /** - * Get the current sockaddr for the socket - */ - void GetSocketAddr(nsAString& aAddrStr); - -private: - UnixSocketConsumerIO* mIO; -}; - -} // namespace ipc -} // namepsace mozilla - -#endif // mozilla_ipc_unixsocket_h diff --git a/ipc/unixsocket/moz.build b/ipc/unixsocket/moz.build index 55ce3b84fc46..9a6b4fec1bf6 100644 --- a/ipc/unixsocket/moz.build +++ b/ipc/unixsocket/moz.build @@ -9,7 +9,6 @@ EXPORTS.mozilla.ipc += [ 'ListenSocket.h', 'SocketBase.h', 'StreamSocket.h', - 'UnixSocket.h', 'UnixSocketConnector.h' ] @@ -18,7 +17,6 @@ SOURCES += [ 'ListenSocket.cpp', 'SocketBase.cpp', 'StreamSocket.cpp', - 'UnixSocket.cpp', 'UnixSocketConnector.cpp' ] diff --git a/js/src/builtin/Object.cpp b/js/src/builtin/Object.cpp index 30c85f4cc87a..6d3413c0c1b9 100644 --- a/js/src/builtin/Object.cpp +++ b/js/src/builtin/Object.cpp @@ -555,6 +555,16 @@ js::obj_hasOwnProperty(JSContext* cx, unsigned argc, Value* vp) jsid id; if (args.thisv().isObject() && ValueToId(cx, idValue, &id)) { JSObject* obj = &args.thisv().toObject(); + +#ifndef RELEASE_BUILD + if (obj->is() && id == NameToId(cx->names().source)) { + if (JSScript* script = cx->currentScript()) { + const char* filename = script->filename(); + cx->compartment()->addTelemetry(filename, JSCompartment::RegExpSourceProperty); + } + } +#endif + Shape* prop; if (obj->isNative() && NativeLookupOwnProperty(cx, &obj->as(), id, &prop)) diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 5537b2829bd0..9be542b9533a 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -2110,7 +2110,7 @@ static bool ReportLargeAllocationFailure(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - void* buf = cx->runtime()->onOutOfMemoryCanGC(NULL, JSRuntime::LARGE_ALLOCATION); + void* buf = cx->runtime()->onOutOfMemoryCanGC(AllocFunction::Malloc, JSRuntime::LARGE_ALLOCATION); js_free(buf); args.rval().setUndefined(); return true; diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index b269efb4d01b..30d5a4b4112a 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -133,7 +133,6 @@ Zone::sweepBreakpoints(FreeOp* fop) MOZ_ASSERT(isGCSweepingOrCompacting()); for (ZoneCellIterUnderGC i(this, AllocKind::SCRIPT); !i.done(); i.next()) { JSScript* script = i.get(); - MOZ_ASSERT_IF(isGCSweeping(), script->zone()->isGCSweeping()); if (!script->hasAnyBreakpointsOrStepMode()) continue; @@ -148,8 +147,16 @@ Zone::sweepBreakpoints(FreeOp* fop) for (Breakpoint* bp = site->firstBreakpoint(); bp; bp = nextbp) { nextbp = bp->nextInSite(); HeapPtrNativeObject& dbgobj = bp->debugger->toJSObjectRef(); + + // If we are sweeping, then we expect the script and the + // debugger object to be swept in the same zone group, except if + // the breakpoint was added after we computed the zone + // groups. In this case both script and debugger object must be + // live. MOZ_ASSERT_IF(isGCSweeping() && dbgobj->zone()->isCollecting(), - dbgobj->zone()->isGCSweeping()); + dbgobj->zone()->isGCSweeping() || + (!scriptGone && dbgobj->asTenured().isMarked())); + bool dying = scriptGone || IsAboutToBeFinalized(&dbgobj); MOZ_ASSERT_IF(!dying, !IsAboutToBeFinalized(&bp->getHandlerRef())); if (dying) diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h index c226e26763f0..8c23d33e8cdb 100644 --- a/js/src/gc/Zone.h +++ b/js/src/gc/Zone.h @@ -133,8 +133,8 @@ struct Zone : public JS::shadow::Zone, bool isTooMuchMalloc() const { return gcMallocBytes <= 0; } void onTooMuchMalloc(); - void* onOutOfMemory(void* p, size_t nbytes) { - return runtimeFromMainThread()->onOutOfMemory(p, nbytes); + void* onOutOfMemory(js::AllocFunction allocFunc, size_t nbytes, void* reallocPtr = nullptr) { + return runtimeFromMainThread()->onOutOfMemory(allocFunc, nbytes, reallocPtr); } void reportAllocationOverflow() { js::ReportAllocationOverflow(nullptr); } diff --git a/js/src/jit-test/tests/gc/bug-1155455.js b/js/src/jit-test/tests/gc/bug-1155455.js new file mode 100644 index 000000000000..6516d2105d88 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1155455.js @@ -0,0 +1,17 @@ +// |jit-test| error: TypeError +if (!("gczeal" in this)) + quit(); +var g = newGlobal(); +gczeal(10, 2) +var dbg = Debugger(g); +dbg.onDebuggerStatement = function (frame1) { + function hit(frame2) + hit[0] = "mutated"; + var s = frame1.script; + var offs = s.getLineOffsets(g.line0 + 2); + for (var i = 0; i < offs.length; i++) + s.setBreakpoint(offs[i], {hit: hit}); + return; +}; +var lfGlobal = newGlobal(); +g.eval("var line0 = Error().lineNumber;\n debugger;\nx = 1;\n"); diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 2eb1299042ae..f16801ad3132 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -350,6 +350,43 @@ ICStub::trace(JSTracer* trc) TraceEdge(trc, &updateStub->group(), "baseline-update-group"); break; } + case ICStub::In_Native: { + ICIn_Native *inStub = toIn_Native(); + TraceEdge(trc, &inStub->shape(), "baseline-innative-stub-shape"); + TraceEdge(trc, &inStub->name(), "baseline-innative-stub-name"); + break; + } + case ICStub::In_NativePrototype: { + ICIn_NativePrototype *inStub = toIn_NativePrototype(); + TraceEdge(trc, &inStub->shape(), "baseline-innativeproto-stub-shape"); + TraceEdge(trc, &inStub->name(), "baseline-innativeproto-stub-name"); + TraceEdge(trc, &inStub->holder(), "baseline-innativeproto-stub-holder"); + TraceEdge(trc, &inStub->holderShape(), "baseline-innativeproto-stub-holdershape"); + break; + } + case ICStub::In_NativeDoesNotExist: { + ICIn_NativeDoesNotExist *inStub = toIn_NativeDoesNotExist(); + TraceEdge(trc, &inStub->name(), "baseline-innativedoesnotexist-stub-name"); + JS_STATIC_ASSERT(ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH == 8); + switch (inStub->protoChainDepth()) { + case 0: inStub->toImpl<0>()->traceShapes(trc); break; + case 1: inStub->toImpl<1>()->traceShapes(trc); break; + case 2: inStub->toImpl<2>()->traceShapes(trc); break; + case 3: inStub->toImpl<3>()->traceShapes(trc); break; + case 4: inStub->toImpl<4>()->traceShapes(trc); break; + case 5: inStub->toImpl<5>()->traceShapes(trc); break; + case 6: inStub->toImpl<6>()->traceShapes(trc); break; + case 7: inStub->toImpl<7>()->traceShapes(trc); break; + case 8: inStub->toImpl<8>()->traceShapes(trc); break; + default: MOZ_CRASH("Invalid proto stub."); + } + break; + } + case ICStub::In_Dense: { + ICIn_Dense *inStub = toIn_Dense(); + TraceEdge(trc, &inStub->shape(), "baseline-in-dense-shape"); + break; + } case ICStub::GetName_Global: { ICGetName_Global* globalStub = toGetName_Global(); TraceEdge(trc, &globalStub->shape(), "baseline-global-stub-shape"); @@ -3768,23 +3805,30 @@ ArgumentsGetElemStubExists(ICGetElem_Fallback* stub, ICGetElem_Arguments::Which return false; } +static bool +IsOptimizableElementPropertyName(JSContext *cx, HandleValue key, MutableHandleId idp) +{ + if (!key.isString()) + return false; + + // Convert to interned property name. + if (!ValueToId(cx, key, idp)) + return false; + + uint32_t dummy; + if (!JSID_IS_ATOM(idp) || JSID_TO_ATOM(idp)->isIndex(&dummy)) + return false; + + return true; +} static bool TryAttachNativeGetValueElemStub(JSContext* cx, HandleScript script, jsbytecode* pc, ICGetElem_Fallback* stub, HandleNativeObject obj, HandleValue key) { - // Native-object GetElem stubs can't deal with non-string keys. - if (!key.isString()) - return true; - - // Convert to interned property name. RootedId id(cx); - if (!ValueToId(cx, key, &id)) - return false; - - uint32_t dummy; - if (!JSID_IS_ATOM(id) || JSID_TO_ATOM(id)->isIndex(&dummy)) + if (!IsOptimizableElementPropertyName(cx, key, &id)) return true; RootedPropertyName propName(cx, JSID_TO_ATOM(id)->asPropertyName()); @@ -3841,17 +3885,9 @@ TryAttachNativeGetAccessorElemStub(JSContext* cx, HandleScript script, jsbytecod HandleValue key, bool* attached) { MOZ_ASSERT(!*attached); - // Native-object GetElem stubs can't deal with non-string keys. - if (!key.isString()) - return true; - // Convert to interned property name. RootedId id(cx); - if (!ValueToId(cx, key, &id)) - return false; - - uint32_t dummy; - if (!JSID_IS_ATOM(id) || JSID_TO_ATOM(id)->isIndex(&dummy)) + if (!IsOptimizableElementPropertyName(cx, key, &id)) return true; RootedPropertyName propName(cx, JSID_TO_ATOM(id)->asPropertyName()); @@ -3964,6 +4000,14 @@ TypedThingRequiresFloatingPoint(JSObject* obj) type == Scalar::Float64; } +static bool +IsNativeDenseElementAccess(HandleObject obj, HandleValue key) +{ + if (obj->isNative() && key.isInt32() && key.toInt32() >= 0 && !IsAnyTypedArray(obj.get())) + return true; + return false; +} + static bool TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_Fallback* stub, HandleValue lhs, HandleValue rhs, HandleValue res) @@ -4027,30 +4071,28 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ } } - if (obj->isNative()) { - // Check for NativeObject[int] dense accesses. - if (rhs.isInt32() && rhs.toInt32() >= 0 && !IsAnyTypedArray(obj.get())) { - JitSpew(JitSpew_BaselineIC, " Generating GetElem(Native[Int32] dense) stub"); - ICGetElem_Dense::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(), - obj->as().lastProperty(), isCallElem); - ICStub* denseStub = compiler.getStub(compiler.getStubSpace(script)); - if (!denseStub) - return false; + // Check for NativeObject[int] dense accesses. + if (IsNativeDenseElementAccess(obj, rhs)) { + JitSpew(JitSpew_BaselineIC, " Generating GetElem(Native[Int32] dense) stub"); + ICGetElem_Dense::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(), + obj->as().lastProperty(), isCallElem); + ICStub* denseStub = compiler.getStub(compiler.getStubSpace(script)); + if (!denseStub) + return false; - stub->addNewStub(denseStub); - return true; - } + stub->addNewStub(denseStub); + return true; + } - // Check for NativeObject[id] shape-optimizable accesses. - if (rhs.isString()) { - RootedScript rootedScript(cx, script); - if (!TryAttachNativeGetValueElemStub(cx, rootedScript, pc, stub, - obj.as(), rhs)) - { - return false; - } - script = rootedScript; + // Check for NativeObject[id] shape-optimizable accesses. + if (obj->isNative() && rhs.isString()) { + RootedScript rootedScript(cx, script); + if (!TryAttachNativeGetValueElemStub(cx, rootedScript, pc, stub, + obj.as(), rhs)) + { + return false; } + script = rootedScript; } // Check for TypedArray[int] => Number and TypedObject[int] => Number accesses. @@ -5193,10 +5235,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_ } // Try to generate new stubs. - if (obj->isNative() && - !IsAnyTypedArray(obj.get()) && - index.isInt32() && index.toInt32() >= 0 && - !rhs.isMagic(JS_ELEMENTS_HOLE)) + if (IsNativeDenseElementAccess(obj, index) && !rhs.isMagic(JS_ELEMENTS_HOLE)) { HandleNativeObject nobj = obj.as(); @@ -5817,9 +5856,100 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm) // static bool -DoInFallback(JSContext* cx, ICIn_Fallback* stub, HandleValue key, HandleValue objValue, - MutableHandleValue res) +TryAttachDenseInStub(JSContext *cx, HandleScript script, ICIn_Fallback *stub, + HandleValue key, HandleObject obj, bool *attached) { + MOZ_ASSERT(!*attached); + + if (!IsNativeDenseElementAccess(obj, key)) + return true; + + JitSpew(JitSpew_BaselineIC, " Generating In(Native[Int32] dense) stub"); + ICIn_Dense::Compiler compiler(cx, obj->as().lastProperty()); + ICStub *denseStub = compiler.getStub(compiler.getStubSpace(script)); + if (!denseStub) + return false; + + *attached = true; + stub->addNewStub(denseStub); + return true; +} + +static bool +TryAttachNativeInStub(JSContext *cx, HandleScript script, ICIn_Fallback *stub, + HandleValue key, HandleObject obj, bool *attached) +{ + MOZ_ASSERT(!*attached); + + RootedId id(cx); + if (!IsOptimizableElementPropertyName(cx, key, &id)) + return true; + + RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName()); + RootedShape shape(cx); + RootedObject holder(cx); + if (!EffectlesslyLookupProperty(cx, obj, name, &holder, &shape)) + return false; + + if (IsCacheableGetPropReadSlot(obj, holder, shape)) { + ICStub::Kind kind = (obj == holder) ? ICStub::In_Native + : ICStub::In_NativePrototype; + JitSpew(JitSpew_BaselineIC, " Generating In(Native %s) stub", + (obj == holder) ? "direct" : "prototype"); + ICInNativeCompiler compiler(cx, kind, obj, holder, name); + ICStub *newStub = compiler.getStub(compiler.getStubSpace(script)); + if (!newStub) + return false; + + *attached = true; + stub->addNewStub(newStub); + return true; + } + + return true; +} + +static bool +TryAttachNativeInDoesNotExistStub(JSContext *cx, HandleScript script, + ICIn_Fallback *stub, HandleValue key, + HandleObject obj, bool *attached) +{ + MOZ_ASSERT(!*attached); + + RootedId id(cx); + if (!IsOptimizableElementPropertyName(cx, key, &id)) + return true; + + // Check if does-not-exist can be confirmed on property. + RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName()); + RootedObject lastProto(cx); + size_t protoChainDepth = SIZE_MAX; + if (!CheckHasNoSuchProperty(cx, obj, name, &lastProto, &protoChainDepth)) + return true; + MOZ_ASSERT(protoChainDepth < SIZE_MAX); + + if (protoChainDepth > ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH) + return true; + + // Confirmed no-such-property. Add stub. + JitSpew(JitSpew_BaselineIC, " Generating In_NativeDoesNotExist stub"); + ICInNativeDoesNotExistCompiler compiler(cx, obj, name, protoChainDepth); + ICStub *newStub = compiler.getStub(compiler.getStubSpace(script)); + if (!newStub) + return false; + + *attached = true; + stub->addNewStub(newStub); + return true; +} + +static bool +DoInFallback(JSContext *cx, BaselineFrame *frame, ICIn_Fallback *stub_, + HandleValue key, HandleValue objValue, MutableHandleValue res) +{ + // This fallback stub may trigger debug mode toggling. + DebugModeOSRVolatileStub stub(frame, stub_); + FallbackICSpew(cx, stub, "In"); if (!objValue.isObject()) { @@ -5832,13 +5962,39 @@ DoInFallback(JSContext* cx, ICIn_Fallback* stub, HandleValue key, HandleValue ob bool cond = false; if (!OperatorIn(cx, key, obj, &cond)) return false; - res.setBoolean(cond); + + if (stub.invalid()) + return true; + + if (stub->numOptimizedStubs() >= ICIn_Fallback::MAX_OPTIMIZED_STUBS) + return true; + + if (obj->isNative()) { + RootedScript script(cx, frame->script()); + bool attached = false; + if (cond) { + if (!TryAttachDenseInStub(cx, script, stub, key, obj, &attached)) + return false; + if (attached) + return true; + if (!TryAttachNativeInStub(cx, script, stub, key, obj, &attached)) + return false; + if (attached) + return true; + } else { + if (!TryAttachNativeInDoesNotExistStub(cx, script, stub, key, obj, &attached)) + return false; + if (attached) + return true; + } + } + return true; } -typedef bool (*DoInFallbackFn)(JSContext*, ICIn_Fallback*, HandleValue, HandleValue, - MutableHandleValue); +typedef bool (*DoInFallbackFn)(JSContext *, BaselineFrame *, ICIn_Fallback *, HandleValue, + HandleValue, MutableHandleValue); static const VMFunction DoInFallbackInfo = FunctionInfo(DoInFallback, TailCall, PopValues(2)); @@ -5855,10 +6011,182 @@ ICIn_Fallback::Compiler::generateStubCode(MacroAssembler& masm) masm.pushValue(R1); masm.pushValue(R0); masm.push(BaselineStubReg); + masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); return tailCallVM(DoInFallbackInfo, masm); } +bool +ICInNativeCompiler::generateStubCode(MacroAssembler &masm) +{ + Label failure, failurePopR0Scratch; + + masm.branchTestString(Assembler::NotEqual, R0, &failure); + masm.branchTestObject(Assembler::NotEqual, R1, &failure); + + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); + Register scratch = regs.takeAny(); + + // Check key identity. + Register strExtract = masm.extractString(R0, ExtractTemp0); + masm.loadPtr(Address(BaselineStubReg, ICInNativeStub::offsetOfName()), scratch); + masm.branchPtr(Assembler::NotEqual, strExtract, scratch, &failure); + + // Unbox and shape guard object. + Register objReg = masm.extractObject(R1, ExtractTemp0); + masm.loadPtr(Address(BaselineStubReg, ICInNativeStub::offsetOfShape()), scratch); + masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure); + + if (kind == ICStub::In_NativePrototype) { + // Shape guard holder. Use R0 scrachReg since on x86 there're not enough registers. + Register holderReg = R0.scratchReg(); + masm.push(R0.scratchReg()); + masm.loadPtr(Address(BaselineStubReg, ICIn_NativePrototype::offsetOfHolder()), + holderReg); + masm.loadPtr(Address(BaselineStubReg, ICIn_NativePrototype::offsetOfHolderShape()), + scratch); + masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failurePopR0Scratch); + masm.addPtr(Imm32(sizeof(size_t)), StackPointer); + } + + masm.moveValue(BooleanValue(true), R0); + + EmitReturnFromIC(masm); + + // Failure case - jump to next stub + masm.bind(&failurePopR0Scratch); + masm.pop(R0.scratchReg()); + masm.bind(&failure); + EmitStubGuardFailure(masm); + return true; +} + +ICStub * +ICInNativeDoesNotExistCompiler::getStub(ICStubSpace *space) +{ + AutoShapeVector shapes(cx); + if (!shapes.append(obj_->as().lastProperty())) + return nullptr; + + if (!GetProtoShapes(obj_, protoChainDepth_, &shapes)) + return nullptr; + + JS_STATIC_ASSERT(ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH == 8); + + ICStub *stub = nullptr; + switch (protoChainDepth_) { + case 0: stub = getStubSpecific<0>(space, &shapes); break; + case 1: stub = getStubSpecific<1>(space, &shapes); break; + case 2: stub = getStubSpecific<2>(space, &shapes); break; + case 3: stub = getStubSpecific<3>(space, &shapes); break; + case 4: stub = getStubSpecific<4>(space, &shapes); break; + case 5: stub = getStubSpecific<5>(space, &shapes); break; + case 6: stub = getStubSpecific<6>(space, &shapes); break; + case 7: stub = getStubSpecific<7>(space, &shapes); break; + case 8: stub = getStubSpecific<8>(space, &shapes); break; + default: MOZ_CRASH("ProtoChainDepth too high."); + } + if (!stub) + return nullptr; + return stub; +} + +bool +ICInNativeDoesNotExistCompiler::generateStubCode(MacroAssembler &masm) +{ + Label failure, failurePopR0Scratch; + + masm.branchTestString(Assembler::NotEqual, R0, &failure); + masm.branchTestObject(Assembler::NotEqual, R1, &failure); + + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); + Register scratch = regs.takeAny(); + +#ifdef DEBUG + // Ensure that protoChainDepth_ matches the protoChainDepth stored on the stub. + { + Label ok; + masm.load16ZeroExtend(Address(BaselineStubReg, ICStub::offsetOfExtra()), scratch); + masm.branch32(Assembler::Equal, scratch, Imm32(protoChainDepth_), &ok); + masm.assumeUnreachable("Non-matching proto chain depth on stub."); + masm.bind(&ok); + } +#endif // DEBUG + + // Check key identity. + Register strExtract = masm.extractString(R0, ExtractTemp0); + masm.loadPtr(Address(BaselineStubReg, ICIn_NativeDoesNotExist::offsetOfName()), scratch); + masm.branchPtr(Assembler::NotEqual, strExtract, scratch, &failure); + + // Unbox and guard against old shape. + Register objReg = masm.extractObject(R1, ExtractTemp0); + masm.loadPtr(Address(BaselineStubReg, ICIn_NativeDoesNotExist::offsetOfShape(0)), + scratch); + masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure); + + // Check the proto chain. + Register protoReg = R0.scratchReg(); + masm.push(R0.scratchReg()); + for (size_t i = 0; i < protoChainDepth_; ++i) { + masm.loadObjProto(i == 0 ? objReg : protoReg, protoReg); + masm.branchTestPtr(Assembler::Zero, protoReg, protoReg, &failurePopR0Scratch); + size_t shapeOffset = ICIn_NativeDoesNotExistImpl<0>::offsetOfShape(i + 1); + masm.loadPtr(Address(BaselineStubReg, shapeOffset), scratch); + masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratch, &failurePopR0Scratch); + } + masm.addPtr(Imm32(sizeof(size_t)), StackPointer); + + // Shape and type checks succeeded, ok to proceed. + masm.moveValue(BooleanValue(false), R0); + + EmitReturnFromIC(masm); + + masm.bind(&failurePopR0Scratch); + masm.pop(R0.scratchReg()); + masm.bind(&failure); + EmitStubGuardFailure(masm); + return true; +} + +bool +ICIn_Dense::Compiler::generateStubCode(MacroAssembler &masm) +{ + Label failure; + + masm.branchTestInt32(Assembler::NotEqual, R0, &failure); + masm.branchTestObject(Assembler::NotEqual, R1, &failure); + + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); + Register scratch = regs.takeAny(); + + // Unbox and shape guard object. + Register obj = masm.extractObject(R1, ExtractTemp0); + masm.loadPtr(Address(BaselineStubReg, ICIn_Dense::offsetOfShape()), scratch); + masm.branchTestObjShape(Assembler::NotEqual, obj, scratch, &failure); + + // Load obj->elements. + masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); + + // Unbox key and bounds check. + Address initLength(scratch, ObjectElements::offsetOfInitializedLength()); + Register key = masm.extractInt32(R0, ExtractTemp0); + masm.branch32(Assembler::BelowOrEqual, initLength, key, &failure); + + // Hole check. + JS_STATIC_ASSERT(sizeof(Value) == 8); + BaseIndex element(scratch, key, TimesEight); + masm.branchTestMagic(Assembler::Equal, element, &failure); + + masm.moveValue(BooleanValue(true), R0); + + EmitReturnFromIC(masm); + + // Failure case - jump to next stub + masm.bind(&failure); + EmitStubGuardFailure(masm); + return true; +} + // Try to update all existing GetProp/GetName getter call stubs that match the // given holder in place with a new shape and getter. fallbackStub can be // either an ICGetProp_Fallback or an ICGetName_Fallback. @@ -7007,9 +7335,10 @@ TryAttachPrimitiveGetPropStub(JSContext* cx, HandleScript script, jsbytecode* pc } static bool -TryAttachNativeDoesNotExistStub(JSContext* cx, HandleScript script, jsbytecode* pc, - ICGetProp_Fallback* stub, HandlePropertyName name, - HandleValue val, bool* attached) +TryAttachNativeGetPropDoesNotExistStub(JSContext *cx, HandleScript script, + jsbytecode *pc, ICGetProp_Fallback *stub, + HandlePropertyName name, HandleValue val, + bool *attached) { MOZ_ASSERT(!*attached); @@ -7194,7 +7523,7 @@ DoGetPropFallback(JSContext* cx, BaselineFrame* frame, ICGetProp_Fallback* stub_ if (res.isUndefined()) { // Try attaching property-not-found optimized stub for undefined results. - if (!TryAttachNativeDoesNotExistStub(cx, script, pc, stub, name, val, &attached)) + if (!TryAttachNativeGetPropDoesNotExistStub(cx, script, pc, stub, name, val, &attached)) return false; if (attached) return true; @@ -12043,6 +12372,64 @@ ICSetElem_TypedArray::ICSetElem_TypedArray(JitCode* stubCode, Shape* shape, Scal extra_ |= (static_cast(expectOutOfBounds) << 8); } +ICInNativeStub::ICInNativeStub(ICStub::Kind kind, JitCode *stubCode, HandleShape shape, + HandlePropertyName name) + : ICStub(kind, stubCode), + shape_(shape), + name_(name) +{ } + +ICIn_NativePrototype::ICIn_NativePrototype(JitCode *stubCode, HandleShape shape, + HandlePropertyName name, HandleObject holder, + HandleShape holderShape) + : ICInNativeStub(In_NativePrototype, stubCode, shape, name), + holder_(holder), + holderShape_(holderShape) +{ } + +ICIn_NativeDoesNotExist::ICIn_NativeDoesNotExist(JitCode *stubCode, size_t protoChainDepth, + HandlePropertyName name) + : ICStub(In_NativeDoesNotExist, stubCode), + name_(name) +{ + MOZ_ASSERT(protoChainDepth <= MAX_PROTO_CHAIN_DEPTH); + extra_ = protoChainDepth; +} + +/* static */ size_t +ICIn_NativeDoesNotExist::offsetOfShape(size_t idx) +{ + MOZ_ASSERT(ICIn_NativeDoesNotExistImpl<0>::offsetOfShape(idx) == + ICIn_NativeDoesNotExistImpl< + ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH>::offsetOfShape(idx)); + return ICIn_NativeDoesNotExistImpl<0>::offsetOfShape(idx); +} + +template +ICIn_NativeDoesNotExistImpl::ICIn_NativeDoesNotExistImpl( + JitCode *stubCode, const AutoShapeVector *shapes, HandlePropertyName name) + : ICIn_NativeDoesNotExist(stubCode, ProtoChainDepth, name) +{ + MOZ_ASSERT(shapes->length() == NumShapes); + for (size_t i = 0; i < NumShapes; i++) + shapes_[i].init((*shapes)[i]); +} + +ICInNativeDoesNotExistCompiler::ICInNativeDoesNotExistCompiler( + JSContext *cx, HandleObject obj, HandlePropertyName name, size_t protoChainDepth) + : ICStubCompiler(cx, ICStub::In_NativeDoesNotExist), + obj_(cx, obj), + name_(cx, name), + protoChainDepth_(protoChainDepth) +{ + MOZ_ASSERT(protoChainDepth_ <= ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH); +} + +ICIn_Dense::ICIn_Dense(JitCode *stubCode, HandleShape shape) + : ICStub(In_Dense, stubCode), + shape_(shape) +{ } + ICGetName_Global::ICGetName_Global(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape, uint32_t slot) : ICMonitoredStub(GetName_Global, stubCode, firstMonitorStub), diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 13ed43c41281..29235a416d38 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -409,6 +409,10 @@ class ICEntry _(SetElem_TypedArray) \ \ _(In_Fallback) \ + _(In_Native) \ + _(In_NativePrototype) \ + _(In_NativeDoesNotExist) \ + _(In_Dense) \ \ _(GetName_Fallback) \ _(GetName_Global) \ @@ -3397,6 +3401,8 @@ class ICIn_Fallback : public ICFallbackStub { } public: + static const uint32_t MAX_OPTIMIZED_STUBS = 8; + class Compiler : public ICStubCompiler { protected: bool generateStubCode(MacroAssembler& masm); @@ -3412,6 +3418,225 @@ class ICIn_Fallback : public ICFallbackStub }; }; +// Base class for In_Native and In_NativePrototype stubs. +class ICInNativeStub : public ICStub +{ + HeapPtrShape shape_; + HeapPtrPropertyName name_; + + protected: + ICInNativeStub(ICStub::Kind kind, JitCode *stubCode, HandleShape shape, + HandlePropertyName name); + + public: + HeapPtrShape &shape() { + return shape_; + } + static size_t offsetOfShape() { + return offsetof(ICInNativeStub, shape_); + } + + HeapPtrPropertyName &name() { + return name_; + } + static size_t offsetOfName() { + return offsetof(ICInNativeStub, name_); + } +}; + +// Stub for confirming an own property on a native object. +class ICIn_Native : public ICInNativeStub +{ + friend class ICStubSpace; + + ICIn_Native(JitCode *stubCode, HandleShape shape, HandlePropertyName name) + : ICInNativeStub(In_Native, stubCode, shape, name) + {} +}; + +// Stub for confirming a property on a native object's prototype. Note that due to +// the shape teleporting optimization, we only have to guard on the object's shape +// and the holder's shape. +class ICIn_NativePrototype : public ICInNativeStub +{ + friend class ICStubSpace; + + HeapPtrObject holder_; + HeapPtrShape holderShape_; + + ICIn_NativePrototype(JitCode *stubCode, HandleShape shape, HandlePropertyName name, + HandleObject holder, HandleShape holderShape); + + public: + HeapPtrObject &holder() { + return holder_; + } + HeapPtrShape &holderShape() { + return holderShape_; + } + static size_t offsetOfHolder() { + return offsetof(ICIn_NativePrototype, holder_); + } + static size_t offsetOfHolderShape() { + return offsetof(ICIn_NativePrototype, holderShape_); + } +}; + +// Compiler for In_Native and In_NativePrototype stubs. +class ICInNativeCompiler : public ICStubCompiler +{ + RootedObject obj_; + RootedObject holder_; + RootedPropertyName name_; + + bool generateStubCode(MacroAssembler &masm); + + public: + ICInNativeCompiler(JSContext *cx, ICStub::Kind kind, HandleObject obj, HandleObject holder, + HandlePropertyName name) + : ICStubCompiler(cx, kind), + obj_(cx, obj), + holder_(cx, holder), + name_(cx, name) + {} + + ICStub *getStub(ICStubSpace *space) { + RootedShape shape(cx, obj_->as().lastProperty()); + if (kind == ICStub::In_Native) { + MOZ_ASSERT(obj_ == holder_); + return ICStub::New(space, getStubCode(), shape, name_); + } + + MOZ_ASSERT(obj_ != holder_); + MOZ_ASSERT(kind == ICStub::In_NativePrototype); + RootedShape holderShape(cx, holder_->as().lastProperty()); + return ICStub::New(space, getStubCode(), shape, name_, holder_, + holderShape); + } +}; + +template class ICIn_NativeDoesNotExistImpl; + +class ICIn_NativeDoesNotExist : public ICStub +{ + friend class ICStubSpace; + + HeapPtrPropertyName name_; + + public: + static const size_t MAX_PROTO_CHAIN_DEPTH = 8; + + protected: + ICIn_NativeDoesNotExist(JitCode *stubCode, size_t protoChainDepth, + HandlePropertyName name); + + public: + size_t protoChainDepth() const { + MOZ_ASSERT(extra_ <= MAX_PROTO_CHAIN_DEPTH); + return extra_; + } + HeapPtrPropertyName &name() { + return name_; + } + + template + ICIn_NativeDoesNotExistImpl *toImpl() { + MOZ_ASSERT(ProtoChainDepth == protoChainDepth()); + return static_cast *>(this); + } + + static size_t offsetOfShape(size_t idx); + static size_t offsetOfName() { + return offsetof(ICIn_NativeDoesNotExist, name_); + } +}; + +template +class ICIn_NativeDoesNotExistImpl : public ICIn_NativeDoesNotExist +{ + friend class ICStubSpace; + + public: + static const size_t MAX_PROTO_CHAIN_DEPTH = 8; + static const size_t NumShapes = ProtoChainDepth + 1; + + private: + mozilla::Array shapes_; + + ICIn_NativeDoesNotExistImpl(JitCode *stubCode, const AutoShapeVector *shapes, + HandlePropertyName name); + + public: + void traceShapes(JSTracer *trc) { + for (size_t i = 0; i < NumShapes; i++) + TraceEdge(trc, &shapes_[i], "baseline-innativedoesnotexist-stub-shape"); + } + + static size_t offsetOfShape(size_t idx) { + return offsetof(ICIn_NativeDoesNotExistImpl, shapes_) + (idx * sizeof(HeapPtrShape)); + } +}; + +class ICInNativeDoesNotExistCompiler : public ICStubCompiler +{ + RootedObject obj_; + RootedPropertyName name_; + size_t protoChainDepth_; + + protected: + virtual int32_t getKey() const { + return static_cast(kind) | (static_cast(protoChainDepth_) << 16); + } + + bool generateStubCode(MacroAssembler &masm); + + public: + ICInNativeDoesNotExistCompiler(JSContext *cx, HandleObject obj, HandlePropertyName name, + size_t protoChainDepth); + + template + ICStub *getStubSpecific(ICStubSpace *space, const AutoShapeVector *shapes) { + return ICStub::New>(space, getStubCode(), + shapes, name_); + } + + ICStub *getStub(ICStubSpace *space); +}; + +class ICIn_Dense : public ICStub +{ + friend class ICStubSpace; + + HeapPtrShape shape_; + + ICIn_Dense(JitCode *stubCode, HandleShape shape); + + public: + HeapPtrShape &shape() { + return shape_; + } + static size_t offsetOfShape() { + return offsetof(ICIn_Dense, shape_); + } + + class Compiler : public ICStubCompiler { + RootedShape shape_; + + protected: + bool generateStubCode(MacroAssembler &masm); + + public: + Compiler(JSContext *cx, Shape *shape) + : ICStubCompiler(cx, ICStub::In_Dense), + shape_(cx, shape) + {} + + ICStub *getStub(ICStubSpace *space) { + return ICStub::New(space, getStubCode(), shape_); + } + }; +}; + // GetName // JSOP_GETNAME // JSOP_GETGNAME diff --git a/js/src/jsalloc.cpp b/js/src/jsalloc.cpp index e8e135e4588a..2eaaf49ccae8 100644 --- a/js/src/jsalloc.cpp +++ b/js/src/jsalloc.cpp @@ -11,9 +11,9 @@ using namespace js; void* -TempAllocPolicy::onOutOfMemory(void* p, size_t nbytes) +TempAllocPolicy::onOutOfMemory(AllocFunction allocFunc, size_t nbytes, void* reallocPtr) { - return static_cast(cx_)->onOutOfMemory(p, nbytes); + return static_cast(cx_)->onOutOfMemory(allocFunc, nbytes, reallocPtr); } void diff --git a/js/src/jsalloc.h b/js/src/jsalloc.h index a15c53040215..613b9836c221 100644 --- a/js/src/jsalloc.h +++ b/js/src/jsalloc.h @@ -19,6 +19,12 @@ namespace js { +enum class AllocFunction { + Malloc, + Calloc, + Realloc +}; + struct ContextFriendFields; /* Policy for using system memory functions and doing no error reporting. */ @@ -51,7 +57,8 @@ class TempAllocPolicy * Non-inline helper to call JSRuntime::onOutOfMemory with minimal * code bloat. */ - JS_FRIEND_API(void*) onOutOfMemory(void* p, size_t nbytes); + JS_FRIEND_API(void*) onOutOfMemory(AllocFunction allocFunc, size_t nbytes, + void* reallocPtr = nullptr); public: MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_((ContextFriendFields*) cx) {} // :( @@ -61,7 +68,7 @@ class TempAllocPolicy T* pod_malloc(size_t numElems) { T* p = js_pod_malloc(numElems); if (MOZ_UNLIKELY(!p)) - p = static_cast(onOutOfMemory(nullptr, numElems * sizeof(T))); + p = static_cast(onOutOfMemory(AllocFunction::Malloc, numElems * sizeof(T))); return p; } @@ -69,7 +76,7 @@ class TempAllocPolicy T* pod_calloc(size_t numElems) { T* p = js_pod_calloc(numElems); if (MOZ_UNLIKELY(!p)) - p = static_cast(onOutOfMemory(reinterpret_cast(1), numElems * sizeof(T))); + p = static_cast(onOutOfMemory(AllocFunction::Calloc, numElems * sizeof(T))); return p; } @@ -77,7 +84,7 @@ class TempAllocPolicy T* pod_realloc(T* prior, size_t oldSize, size_t newSize) { T* p2 = js_pod_realloc(prior, oldSize, newSize); if (MOZ_UNLIKELY(!p2)) - p2 = static_cast(onOutOfMemory(prior, newSize * sizeof(T))); + p2 = static_cast(onOutOfMemory(AllocFunction::Realloc, newSize * sizeof(T), prior)); return p2; } diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index cba1c7af027e..bcf115c3849c 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -164,8 +164,8 @@ class ExclusiveContext : public ContextFriendFields, return thing->compartment() == compartment_; } - void* onOutOfMemory(void* p, size_t nbytes) { - return runtime_->onOutOfMemory(p, nbytes, maybeJSContext()); + void* onOutOfMemory(js::AllocFunction allocFunc, size_t nbytes, void* reallocPtr = nullptr) { + return runtime_->onOutOfMemory(allocFunc, nbytes, reallocPtr, maybeJSContext()); } /* Clear the pending exception (if any) due to OOM. */ diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index f19d88d85080..4883c071b518 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -591,6 +591,7 @@ struct JSCompartment DeprecatedLetExpression = 5, // Added in JS 1.7 DeprecatedNoSuchMethod = 6, // JS 1.7+ DeprecatedFlagsArgument = 7, // JS 1.3 or older + RegExpSourceProperty = 8, // ES5 DeprecatedLanguageExtensionCount }; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index d7d448c11a1e..5c33da511095 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3002,6 +3002,15 @@ js::GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id, return ok; } +#ifndef RELEASE_BUILD + if (obj->is() && id == NameToId(cx->names().source)) { + if (JSScript* script = cx->currentScript()) { + const char* filename = script->filename(); + cx->compartment()->addTelemetry(filename, JSCompartment::RegExpSourceProperty); + } + } +#endif + RootedShape shape(cx); if (!NativeLookupOwnProperty(cx, obj.as(), id, &shape)) return false; diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index c3b090ad7c4d..d1944a90eb92 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -880,7 +880,7 @@ class BreakpointSite { * Nothing else causes a breakpoint to be retained, so if its script or * debugger is collected, the breakpoint is destroyed during GC sweep phase, * even if the debugger compartment isn't being GC'd. This is implemented in - * JSCompartment::sweepBreakpoints. + * Zone::sweepBreakpoints. */ class Breakpoint { friend struct ::JSCompartment; diff --git a/js/src/vm/MallocProvider.h b/js/src/vm/MallocProvider.h index e21034408d65..d80b05a0cbc7 100644 --- a/js/src/vm/MallocProvider.h +++ b/js/src/vm/MallocProvider.h @@ -68,7 +68,7 @@ struct MallocProvider client()->reportAllocationOverflow(); return nullptr; } - return (T*)client()->onOutOfMemory(nullptr, numElems * sizeof(T)); + return (T*)client()->onOutOfMemory(AllocFunction::Malloc, numElems * sizeof(T)); } template @@ -87,7 +87,7 @@ struct MallocProvider client()->updateMallocCounter(bytes); return p; } - return (T*)client()->onOutOfMemory(nullptr, bytes); + return (T*)client()->onOutOfMemory(AllocFunction::Malloc, bytes); } template @@ -112,7 +112,7 @@ struct MallocProvider client()->reportAllocationOverflow(); return nullptr; } - return (T*)client()->onOutOfMemory(reinterpret_cast(1), numElems * sizeof(T)); + return (T*)client()->onOutOfMemory(AllocFunction::Calloc, numElems * sizeof(T)); } template @@ -131,7 +131,7 @@ struct MallocProvider client()->updateMallocCounter(bytes); return p; } - return (T*)client()->onOutOfMemory(reinterpret_cast(1), bytes); + return (T*)client()->onOutOfMemory(AllocFunction::Calloc, bytes); } template @@ -155,7 +155,7 @@ struct MallocProvider client()->reportAllocationOverflow(); return nullptr; } - return (T*)client()->onOutOfMemory(prior, newSize * sizeof(T)); + return (T*)client()->onOutOfMemory(AllocFunction::Realloc, newSize * sizeof(T), prior); } JS_DECLARE_NEW_METHODS(new_, pod_malloc, MOZ_ALWAYS_INLINE) diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index c35032f9be71..0d7c3150d0df 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -737,14 +737,11 @@ JSRuntime::onTooMuchMalloc() } JS_FRIEND_API(void*) -JSRuntime::onOutOfMemory(void* p, size_t nbytes) +JSRuntime::onOutOfMemory(AllocFunction allocFunc, size_t nbytes, void* reallocPtr, + JSContext* maybecx) { - return onOutOfMemory(p, nbytes, nullptr); -} + MOZ_ASSERT_IF(allocFunc != AllocFunction::Realloc, !reallocPtr); -JS_FRIEND_API(void*) -JSRuntime::onOutOfMemory(void* p, size_t nbytes, JSContext* cx) -{ if (isHeapBusy()) return nullptr; @@ -753,25 +750,34 @@ JSRuntime::onOutOfMemory(void* p, size_t nbytes, JSContext* cx) * all the allocations and released the empty GC chunks. */ gc.onOutOfMallocMemory(); - if (!p) + void* p; + switch (allocFunc) { + case AllocFunction::Malloc: p = js_malloc(nbytes); - else if (p == reinterpret_cast(1)) + break; + case AllocFunction::Calloc: p = js_calloc(nbytes); - else - p = js_realloc(p, nbytes); + break; + case AllocFunction::Realloc: + p = js_realloc(reallocPtr, nbytes); + break; + default: + MOZ_CRASH(); + } if (p) return p; - if (cx) - ReportOutOfMemory(cx); + + if (maybecx) + ReportOutOfMemory(maybecx); return nullptr; } void* -JSRuntime::onOutOfMemoryCanGC(void* p, size_t bytes) +JSRuntime::onOutOfMemoryCanGC(AllocFunction allocFunc, size_t bytes, void* reallocPtr) { if (largeAllocationFailureCallback && bytes >= LARGE_ALLOCATION) largeAllocationFailureCallback(largeAllocationFailureCallbackData); - return onOutOfMemory(p, bytes); + return onOutOfMemory(allocFunc, bytes, reallocPtr); } bool diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 753f3c69b0c0..8e6d1cc11193 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -1359,18 +1359,18 @@ struct JSRuntime : public JS::shadow::Runtime, JS_FRIEND_API(void) onTooMuchMalloc(); /* - * This should be called after system malloc/realloc returns nullptr to try - * to recove some memory or to report an error. Failures in malloc and - * calloc are signaled by p == null and p == reinterpret_cast(1). - * Other values of p mean a realloc failure. + * This should be called after system malloc/calloc/realloc returns nullptr + * to try to recove some memory or to report an error. For realloc, the + * original pointer must be passed as reallocPtr. * * The function must be called outside the GC lock. */ - JS_FRIEND_API(void*) onOutOfMemory(void* p, size_t nbytes); - JS_FRIEND_API(void*) onOutOfMemory(void* p, size_t nbytes, JSContext* cx); + JS_FRIEND_API(void*) onOutOfMemory(js::AllocFunction allocator, size_t nbytes, + void* reallocPtr = nullptr, JSContext* maybecx = nullptr); /* onOutOfMemory but can call the largeAllocationFailureCallback. */ - JS_FRIEND_API(void*) onOutOfMemoryCanGC(void* p, size_t bytes); + JS_FRIEND_API(void*) onOutOfMemoryCanGC(js::AllocFunction allocator, size_t nbytes, + void* reallocPtr = nullptr); void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes* runtime); @@ -1434,7 +1434,7 @@ struct JSRuntime : public JS::shadow::Runtime, reportAllocationOverflow(); return nullptr; } - return (T*)onOutOfMemoryCanGC(reinterpret_cast(1), numElems * sizeof(T)); + return (T*)onOutOfMemoryCanGC(js::AllocFunction::Calloc, numElems * sizeof(T)); } template @@ -1446,7 +1446,7 @@ struct JSRuntime : public JS::shadow::Runtime, reportAllocationOverflow(); return nullptr; } - return (T*)onOutOfMemoryCanGC(p, newSize * sizeof(T)); + return (T*)onOutOfMemoryCanGC(js::AllocFunction::Realloc, newSize * sizeof(T), p); } /* diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 0eeabbee3197..59f07b0fd991 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -2218,7 +2218,7 @@ ContainerState::FindOpaqueBackgroundColorInLayer(const PaintedLayerData* aData, // Scan the candidate's display items. nsIntRect deviceRect = aRect; - nsRect appUnitRect = deviceRect.ToAppUnits(mAppUnitsPerDevPixel); + nsRect appUnitRect = ToAppUnits(deviceRect, mAppUnitsPerDevPixel); appUnitRect.ScaleInverseRoundOut(mParameters.mXScale, mParameters.mYScale); for (auto& assignedItem : Reversed(aData->mAssignedDisplayItems)) { @@ -4818,7 +4818,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, // we won't paint if (aChildren->IsOpaque() && !aChildren->NeedsTransparentSurface()) { bounds.ScaleRoundIn(scaleParameters.mXScale, scaleParameters.mYScale); - if (bounds.Contains(pixBounds.ToAppUnits(appUnitsPerDevPixel))) { + if (bounds.Contains(ToAppUnits(pixBounds, appUnitsPerDevPixel))) { // Clear CONTENT_COMPONENT_ALPHA and add CONTENT_OPAQUE instead. flags &= ~Layer::CONTENT_COMPONENT_ALPHA; flags |= Layer::CONTENT_OPAQUE; @@ -5066,7 +5066,7 @@ FrameLayerBuilder::PaintItems(nsTArray& aItems, DrawTarget& aDrawTarget = *aRC->GetDrawTarget(); int32_t appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel(); - nsRect boundRect = aRect.ToAppUnits(appUnitsPerDevPixel); + nsRect boundRect = ToAppUnits(aRect, appUnitsPerDevPixel); boundRect.MoveBy(NSIntPixelsToAppUnits(aOffset.x, appUnitsPerDevPixel), NSIntPixelsToAppUnits(aOffset.y, appUnitsPerDevPixel)); boundRect.ScaleInverseRoundOut(aXScale, aYScale); diff --git a/layout/base/SelectionCarets.cpp b/layout/base/SelectionCarets.cpp index c229f242bf64..889556e41559 100644 --- a/layout/base/SelectionCarets.cpp +++ b/layout/base/SelectionCarets.cpp @@ -538,8 +538,8 @@ SelectionCarets::UpdateSelectionCarets() SetStartFrameVisibility(startFrameVisible); SetEndFrameVisibility(endFrameVisible); - SetStartFramePos(firstRectInRootFrame.BottomLeft()); - SetEndFramePos(lastRectInRootFrame.BottomRight()); + SetStartFramePos(firstRectInRootFrame); + SetEndFramePos(lastRectInRootFrame); SetVisibility(true); // Use half of the first(last) rect as the dragup(dragdown) boundary @@ -892,7 +892,7 @@ SelectionCarets::SetSelectionDirection(nsDirection aDir) } static void -SetFramePos(dom::Element* aElement, const nsPoint& aPosition) +SetFramePos(dom::Element* aElement, const nsRect& aCaretRect) { if (!aElement) { return; @@ -900,9 +900,11 @@ SetFramePos(dom::Element* aElement, const nsPoint& aPosition) nsAutoString styleStr; styleStr.AppendLiteral("left: "); - styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aPosition.x)); + styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aCaretRect.Center().x)); styleStr.AppendLiteral("px; top: "); - styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aPosition.y)); + styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aCaretRect.y)); + styleStr.AppendLiteral("px; padding-top: "); + styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aCaretRect.height)); styleStr.AppendLiteral("px;"); SELECTIONCARETS_LOG_STATIC("Set style: %s", @@ -912,17 +914,19 @@ SetFramePos(dom::Element* aElement, const nsPoint& aPosition) } void -SelectionCarets::SetStartFramePos(const nsPoint& aPosition) +SelectionCarets::SetStartFramePos(const nsRect& aCaretRect) { - SELECTIONCARETS_LOG("x=%d, y=%d", aPosition.x, aPosition.y); - SetFramePos(mPresShell->GetSelectionCaretsStartElement(), aPosition); + SELECTIONCARETS_LOG("x=%d, y=%d, w=%d, h=%d", + aCaretRect.x, aCaretRect.y, aCaretRect.width, aCaretRect.height); + SetFramePos(mPresShell->GetSelectionCaretsStartElement(), aCaretRect); } void -SelectionCarets::SetEndFramePos(const nsPoint& aPosition) +SelectionCarets::SetEndFramePos(const nsRect& aCaretRect) { - SELECTIONCARETS_LOG("x=%d, y=%d", aPosition.y, aPosition.y); - SetFramePos(mPresShell->GetSelectionCaretsEndElement(), aPosition); + SELECTIONCARETS_LOG("x=%d, y=%d, w=%d, h=%d", + aCaretRect.x, aCaretRect.y, aCaretRect.width, aCaretRect.height); + SetFramePos(mPresShell->GetSelectionCaretsEndElement(), aCaretRect); } bool diff --git a/layout/base/SelectionCarets.h b/layout/base/SelectionCarets.h index 7367070fb568..42aea9616fbe 100644 --- a/layout/base/SelectionCarets.h +++ b/layout/base/SelectionCarets.h @@ -147,16 +147,16 @@ private: void SetSelectionDirection(nsDirection aDir); /** - * Move start frame of selection caret to given position. + * Move start frame of selection caret based on current caret pos. * In app units. */ - void SetStartFramePos(const nsPoint& aPosition); + void SetStartFramePos(const nsRect& aCaretRect); /** - * Move end frame of selection caret to given position. + * Move end frame of selection caret based on current caret pos. * In app units. */ - void SetEndFramePos(const nsPoint& aPosition); + void SetEndFramePos(const nsRect& aCaretRect); /** * Check if aPosition is on the start or end frame of the diff --git a/layout/base/TouchCaret.cpp b/layout/base/TouchCaret.cpp index 9f130547dc63..972a32318a31 100644 --- a/layout/base/TouchCaret.cpp +++ b/layout/base/TouchCaret.cpp @@ -249,7 +249,7 @@ TouchCaret::GetCaretYCenterPosition() } void -TouchCaret::SetTouchFramePos(const nsPoint& aOrigin) +TouchCaret::SetTouchFramePos(const nsRect& aCaretRect) { nsCOMPtr presShell = do_QueryReferent(mPresShell); if (!presShell) { @@ -263,14 +263,17 @@ TouchCaret::SetTouchFramePos(const nsPoint& aOrigin) // Convert aOrigin to CSS pixels. nsRefPtr presContext = presShell->GetPresContext(); - int32_t x = presContext->AppUnitsToIntCSSPixels(aOrigin.x); - int32_t y = presContext->AppUnitsToIntCSSPixels(aOrigin.y); + int32_t x = presContext->AppUnitsToIntCSSPixels(aCaretRect.Center().x); + int32_t y = presContext->AppUnitsToIntCSSPixels(aCaretRect.y); + int32_t padding = presContext->AppUnitsToIntCSSPixels(aCaretRect.height); nsAutoString styleStr; styleStr.AppendLiteral("left: "); styleStr.AppendInt(x); styleStr.AppendLiteral("px; top: "); styleStr.AppendInt(y); + styleStr.AppendLiteral("px; padding-top: "); + styleStr.AppendInt(padding); styleStr.AppendLiteral("px;"); TOUCHCARET_LOG("Set style: %s", NS_ConvertUTF16toUTF8(styleStr).get()); @@ -483,32 +486,27 @@ TouchCaret::UpdatePosition() { MOZ_ASSERT(mVisible); - nsPoint pos = GetTouchCaretPosition(); - pos = ClampPositionToScrollFrame(pos); - SetTouchFramePos(pos); + nsRect rect = GetTouchCaretRect(); + rect = ClampRectToScrollFrame(rect); + SetTouchFramePos(rect); } -nsPoint -TouchCaret::GetTouchCaretPosition() +nsRect +TouchCaret::GetTouchCaretRect() { nsRect focusRect; nsIFrame* focusFrame = GetCaretFocusFrame(&focusRect); nsIFrame* rootFrame = GetRootFrame(); - - // Position of the touch caret relative to focusFrame. - nsPoint pos = nsPoint(focusRect.x + (focusRect.width / 2), - focusRect.y + focusRect.height); - // Transform the position to make it relative to root frame. - nsLayoutUtils::TransformPoint(focusFrame, rootFrame, pos); + nsLayoutUtils::TransformRect(focusFrame, rootFrame, focusRect); - return pos; + return focusRect; } -nsPoint -TouchCaret::ClampPositionToScrollFrame(const nsPoint& aPosition) +nsRect +TouchCaret::ClampRectToScrollFrame(const nsRect& aRect) { - nsPoint pos = aPosition; + nsRect rect = aRect; nsIFrame* focusFrame = GetCaretFocusFrame(); nsIFrame* rootFrame = GetRootFrame(); @@ -522,7 +520,7 @@ TouchCaret::ClampPositionToScrollFrame(const nsPoint& aPosition) // Clamp the touch caret in the scroll port. nsLayoutUtils::TransformRect(closestScrollFrame, rootFrame, visualRect); - pos = visualRect.ClampPoint(pos); + rect = rect.Intersect(visualRect); // Get next ancestor scroll frame. closestScrollFrame = @@ -530,7 +528,7 @@ TouchCaret::ClampPositionToScrollFrame(const nsPoint& aPosition) nsGkAtoms::scrollFrame); } - return pos; + return rect; } /* static */void diff --git a/layout/base/TouchCaret.h b/layout/base/TouchCaret.h index c6639a46bd7f..bfb862ae201d 100644 --- a/layout/base/TouchCaret.h +++ b/layout/base/TouchCaret.h @@ -117,22 +117,22 @@ private: nscoord GetCaretYCenterPosition(); /** - * Retrieve the position of the touch caret. - * The returned point is relative to the canvas frame. + * Retrieve the rect of the touch caret. + * The returned rect is relative to the canvas frame. */ - nsPoint GetTouchCaretPosition(); + nsRect GetTouchCaretRect(); /** * Clamp the position of the touch caret to the scroll frame boundary. - * The returned point is relative to the canvas frame. + * The returned rect is relative to the canvas frame. */ - nsPoint ClampPositionToScrollFrame(const nsPoint& aPosition); + nsRect ClampRectToScrollFrame(const nsRect& aRect); /** * Set the position of the touch caret. * Touch caret is an absolute positioned div. */ - void SetTouchFramePos(const nsPoint& aOrigin); + void SetTouchFramePos(const nsRect& aRect); void LaunchExpirationTimer(); void CancelExpirationTimer(); diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index ed6a924a7b4f..08001f5e8bf3 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -34,6 +34,7 @@ #include "nsColor.h" #include "nsCompatibility.h" #include "nsFrameManagerBase.h" +#include "nsRect.h" #include "mozFlushType.h" #include "nsWeakReference.h" #include // for FILE definition @@ -80,8 +81,6 @@ class nsDisplayListBuilder; class nsPIDOMWindow; struct nsPoint; class nsINode; -struct nsIntPoint; -struct nsIntRect; struct nsRect; class nsRegion; class nsRefreshDriver; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 4520beee120f..62b925e4f252 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -5292,7 +5292,7 @@ PresShell::RenderNode(nsIDOMNode* aNode, // combine the area with the supplied region nsIntRect rrectPixels = aRegion->GetBounds(); - nsRect rrect = rrectPixels.ToAppUnits(nsPresContext::AppUnitsPerCSSPixel()); + nsRect rrect = ToAppUnits(rrectPixels, nsPresContext::AppUnitsPerCSSPixel()); area.IntersectRect(area, rrect); nsPresContext* pc = GetPresContext(); diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 181ee12e11be..a81bc2f57cc6 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -966,8 +966,8 @@ nsRefreshDriver::GetRegularTimerInterval(bool *outIsDefault) const return 1000.0 / rate; } -double -nsRefreshDriver::GetThrottledTimerInterval() const +/* static */ double +nsRefreshDriver::GetThrottledTimerInterval() { int32_t rate = Preferences::GetInt("layout.throttled_frame_rate", -1); if (rate <= 0) { @@ -1020,6 +1020,8 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext) mPendingTransaction(0), mCompletedTransaction(0), mFreezeCount(0), + mThrottledFrameRequestInterval(TimeDuration::FromMilliseconds( + GetThrottledTimerInterval())), mThrottled(false), mTestControllingRefreshes(false), mViewManagerFlushIsPending(false), @@ -1031,6 +1033,7 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext) mMostRecentRefreshEpochTime = JS_Now(); mMostRecentRefresh = TimeStamp::Now(); mMostRecentTick = mMostRecentRefresh; + mNextThrottledFrameRequestTick = mMostRecentTick; } nsRefreshDriver::~nsRefreshDriver() @@ -1254,13 +1257,15 @@ DisableHighPrecisionTimersCallback(nsITimer *aTimer, void *aClosure) void nsRefreshDriver::ConfigureHighPrecision() { - bool haveFrameRequestCallbacks = mFrameRequestCallbackDocs.Length() > 0; + bool haveUnthrottledFrameRequestCallbacks = + mFrameRequestCallbackDocs.Length() > 0; // if the only change that's needed is that we need high precision, // then just set that - if (!mThrottled && !mRequestedHighPrecision && haveFrameRequestCallbacks) { + if (!mThrottled && !mRequestedHighPrecision && + haveUnthrottledFrameRequestCallbacks) { SetHighPrecisionTimersEnabled(true); - } else if (mRequestedHighPrecision && !haveFrameRequestCallbacks) { + } else if (mRequestedHighPrecision && !haveUnthrottledFrameRequestCallbacks) { SetHighPrecisionTimersEnabled(false); } } @@ -1328,6 +1333,7 @@ nsRefreshDriver::ObserverCount() const sum += mStyleFlushObservers.Length(); sum += mLayoutFlushObservers.Length(); sum += mFrameRequestCallbackDocs.Length(); + sum += mThrottledFrameRequestCallbackDocs.Length(); sum += mViewManagerFlushIsPending; return sum; } @@ -1453,6 +1459,105 @@ static void GetProfileTimelineSubDocShells(nsDocShell* aRootDocShell, }; } +static void +TakeFrameRequestCallbacksFrom(nsIDocument* aDocument, + nsTArray& aTarget) +{ + aTarget.AppendElement(aDocument); + aDocument->TakeFrameRequestCallbacks(aTarget.LastElement().mCallbacks); +} + +void +nsRefreshDriver::RunFrameRequestCallbacks(int64_t aNowEpoch, TimeStamp aNowTime) +{ + // Grab all of our frame request callbacks up front. + nsTArray + frameRequestCallbacks(mFrameRequestCallbackDocs.Length() + + mThrottledFrameRequestCallbackDocs.Length()); + + // First, grab throttled frame request callbacks. + { + nsTArray docsToRemove; + + // We always tick throttled frame requests if the entire refresh driver is + // throttled, because in that situation throttled frame requests tick at the + // same frequency as non-throttled frame requests. + bool tickThrottledFrameRequests = mThrottled; + + if (!tickThrottledFrameRequests && + aNowTime >= mNextThrottledFrameRequestTick) { + mNextThrottledFrameRequestTick = aNowTime + mThrottledFrameRequestInterval; + tickThrottledFrameRequests = true; + } + + for (nsIDocument* doc : mThrottledFrameRequestCallbackDocs) { + if (tickThrottledFrameRequests) { + // We're ticking throttled documents, so grab this document's requests. + // We don't bother appending to docsToRemove because we're going to + // clear mThrottledFrameRequestCallbackDocs anyway. + TakeFrameRequestCallbacksFrom(doc, frameRequestCallbacks); + } else if (!doc->ShouldThrottleFrameRequests()) { + // This document is no longer throttled, so grab its requests even + // though we're not ticking throttled frame requests right now. If + // this is the first unthrottled document with frame requests, we'll + // enter high precision mode the next time the callback is scheduled. + TakeFrameRequestCallbacksFrom(doc, frameRequestCallbacks); + docsToRemove.AppendElement(doc); + } + } + + // Remove all the documents we're ticking from + // mThrottledFrameRequestCallbackDocs so they can be readded as needed. + if (tickThrottledFrameRequests) { + mThrottledFrameRequestCallbackDocs.Clear(); + } else { + // XXX(seth): We're using this approach to avoid concurrent modification + // of mThrottledFrameRequestCallbackDocs. docsToRemove usually has either + // zero elements or a very small number, so this should be OK in practice. + for (nsIDocument* doc : docsToRemove) { + mThrottledFrameRequestCallbackDocs.RemoveElement(doc); + } + } + } + + // Now grab unthrottled frame request callbacks. + for (nsIDocument* doc : mFrameRequestCallbackDocs) { + TakeFrameRequestCallbacksFrom(doc, frameRequestCallbacks); + } + + // Reset mFrameRequestCallbackDocs so they can be readded as needed. + mFrameRequestCallbackDocs.Clear(); + + profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_START); + int64_t eventTime = aNowEpoch / PR_USEC_PER_MSEC; + for (uint32_t i = 0; i < frameRequestCallbacks.Length(); ++i) { + const DocumentFrameCallbacks& docCallbacks = frameRequestCallbacks[i]; + // XXXbz Bug 863140: GetInnerWindow can return the outer + // window in some cases. + nsPIDOMWindow* innerWindow = docCallbacks.mDocument->GetInnerWindow(); + DOMHighResTimeStamp timeStamp = 0; + if (innerWindow && innerWindow->IsInnerWindow()) { + nsPerformance* perf = innerWindow->GetPerformance(); + if (perf) { + timeStamp = perf->GetDOMTiming()->TimeStampToDOMHighRes(aNowTime); + } + // else window is partially torn down already + } + for (uint32_t j = 0; j < docCallbacks.mCallbacks.Length(); ++j) { + const nsIDocument::FrameRequestCallbackHolder& holder = + docCallbacks.mCallbacks[j]; + nsAutoMicroTask mt; + if (holder.HasWebIDLCallback()) { + ErrorResult ignored; + holder.GetWebIDLCallback()->Call(timeStamp, ignored); + } else { + holder.GetXPCOMCallback()->Sample(eventTime); + } + } + } + profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_END); +} + void nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) { @@ -1543,46 +1648,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) if (i == 0) { // This is the Flush_Style case. - // Grab all of our frame request callbacks up front. - nsTArray - frameRequestCallbacks(mFrameRequestCallbackDocs.Length()); - for (uint32_t i = 0; i < mFrameRequestCallbackDocs.Length(); ++i) { - frameRequestCallbacks.AppendElement(mFrameRequestCallbackDocs[i]); - mFrameRequestCallbackDocs[i]-> - TakeFrameRequestCallbacks(frameRequestCallbacks.LastElement().mCallbacks); - } - // OK, now reset mFrameRequestCallbackDocs so they can be - // readded as needed. - mFrameRequestCallbackDocs.Clear(); - - profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_START); - int64_t eventTime = aNowEpoch / PR_USEC_PER_MSEC; - for (uint32_t i = 0; i < frameRequestCallbacks.Length(); ++i) { - const DocumentFrameCallbacks& docCallbacks = frameRequestCallbacks[i]; - // XXXbz Bug 863140: GetInnerWindow can return the outer - // window in some cases. - nsPIDOMWindow* innerWindow = docCallbacks.mDocument->GetInnerWindow(); - DOMHighResTimeStamp timeStamp = 0; - if (innerWindow && innerWindow->IsInnerWindow()) { - nsPerformance* perf = innerWindow->GetPerformance(); - if (perf) { - timeStamp = perf->GetDOMTiming()->TimeStampToDOMHighRes(aNowTime); - } - // else window is partially torn down already - } - for (uint32_t j = 0; j < docCallbacks.mCallbacks.Length(); ++j) { - const nsIDocument::FrameRequestCallbackHolder& holder = - docCallbacks.mCallbacks[j]; - nsAutoMicroTask mt; - if (holder.HasWebIDLCallback()) { - ErrorResult ignored; - holder.GetWebIDLCallback()->Call(timeStamp, ignored); - } else { - holder.GetXPCOMCallback()->Sample(eventTime); - } - } - } - profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_END); + RunFrameRequestCallbacks(aNowEpoch, aNowTime); if (mPresContext && mPresContext->GetPresShell()) { bool tracingStyleFlush = false; @@ -2025,9 +2091,15 @@ void nsRefreshDriver::ScheduleFrameRequestCallbacks(nsIDocument* aDocument) { NS_ASSERTION(mFrameRequestCallbackDocs.IndexOf(aDocument) == - mFrameRequestCallbackDocs.NoIndex, + mFrameRequestCallbackDocs.NoIndex && + mThrottledFrameRequestCallbackDocs.IndexOf(aDocument) == + mThrottledFrameRequestCallbackDocs.NoIndex, "Don't schedule the same document multiple times"); - mFrameRequestCallbackDocs.AppendElement(aDocument); + if (aDocument->ShouldThrottleFrameRequests()) { + mThrottledFrameRequestCallbackDocs.AppendElement(aDocument); + } else { + mFrameRequestCallbackDocs.AppendElement(aDocument); + } // make sure that the timer is running ConfigureHighPrecision(); @@ -2038,6 +2110,7 @@ void nsRefreshDriver::RevokeFrameRequestCallbacks(nsIDocument* aDocument) { mFrameRequestCallbackDocs.RemoveElement(aDocument); + mThrottledFrameRequestCallbackDocs.RemoveElement(aDocument); ConfigureHighPrecision(); // No need to worry about restarting our timer in slack mode if it's already // running; that will happen automatically when it fires. diff --git a/layout/base/nsRefreshDriver.h b/layout/base/nsRefreshDriver.h index e001e7fa381e..9bc464b5ea34 100644 --- a/layout/base/nsRefreshDriver.h +++ b/layout/base/nsRefreshDriver.h @@ -308,6 +308,8 @@ private: }; typedef nsClassHashtable ImageStartTable; + void RunFrameRequestCallbacks(int64_t aNowEpoch, mozilla::TimeStamp aNowTime); + void Tick(int64_t aNowEpoch, mozilla::TimeStamp aNowTime); enum EnsureTimerStartedFlags { @@ -336,7 +338,7 @@ private: double GetRefreshTimerInterval() const; double GetRegularTimerInterval(bool *outIsDefault = nullptr) const; - double GetThrottledTimerInterval() const; + static double GetThrottledTimerInterval(); bool HaveFrameRequestCallbacks() const { return mFrameRequestCallbackDocs.Length() != 0; @@ -361,6 +363,11 @@ private: uint64_t mCompletedTransaction; uint32_t mFreezeCount; + + // How long we wait between ticks for throttled (which generally means + // non-visible) documents registered with a non-throttled refresh driver. + const mozilla::TimeDuration mThrottledFrameRequestInterval; + bool mThrottled; bool mTestControllingRefreshes; bool mViewManagerFlushIsPending; @@ -379,6 +386,7 @@ private: mozilla::TimeStamp mMostRecentRefresh; mozilla::TimeStamp mMostRecentTick; mozilla::TimeStamp mTickStart; + mozilla::TimeStamp mNextThrottledFrameRequestTick; // separate arrays for each flush type we support ObserverArray mObservers[3]; @@ -390,6 +398,7 @@ private: nsAutoTArray mPresShellsToInvalidateIfHidden; // nsTArray on purpose, because we want to be able to swap. nsTArray mFrameRequestCallbackDocs; + nsTArray mThrottledFrameRequestCallbackDocs; nsTArray mPostRefreshObservers; // Helper struct for processing image requests diff --git a/layout/base/tests/chrome/chrome.ini b/layout/base/tests/chrome/chrome.ini index afe7db848d6d..393b9678f6de 100644 --- a/layout/base/tests/chrome/chrome.ini +++ b/layout/base/tests/chrome/chrome.ini @@ -54,7 +54,7 @@ skip-if = buildapp == 'b2g' [test_fixed_bg_scrolling_repaints.html] skip-if = buildapp == 'b2g' [test_leaf_layers_partition_browser_window.xul] -skip-if = (!debug) || (toolkit == "cocoa") || (buildapp == 'b2g') # Disabled on Mac because of Bug 748219 +skip-if = (!debug) || (toolkit == "cocoa") || (buildapp == 'b2g') || (toolkit == 'windows') # Disabled on Mac because of Bug 748219 [test_no_clip_iframe.xul] skip-if = buildapp == 'b2g' [test_passpointerevents.html] diff --git a/layout/base/tests/test_scroll_event_ordering.html b/layout/base/tests/test_scroll_event_ordering.html index c998b8d1fdfd..8dd67d6426ae 100644 --- a/layout/base/tests/test_scroll_event_ordering.html +++ b/layout/base/tests/test_scroll_event_ordering.html @@ -47,9 +47,16 @@ function doTest() { sendKey("DOWN"); } -SimpleTest.waitForFocus(function() { - SpecialPowers.pushPrefEnv({"set":[[smoothScrollPref, false]]}, doTest); -}); +function prepareTest() { + // Start the test after we've gotten at least one rAF callback, to make sure + // that rAF is no longer throttled. (See bug 1145439.) + window.mozRequestAnimationFrame(function() { + SpecialPowers.pushPrefEnv({"set":[[smoothScrollPref, false]]}, doTest); + }); +} + +SimpleTest.waitForFocus(prepareTest); + diff --git a/layout/forms/crashtests/crashtests.list b/layout/forms/crashtests/crashtests.list index b681da776501..722ac8f7ad37 100644 --- a/layout/forms/crashtests/crashtests.list +++ b/layout/forms/crashtests/crashtests.list @@ -47,7 +47,7 @@ load 478219-1.xhtml load 513113-1.html load 538062-1.xhtml load 570624-1.html -skip-if(B2G) load 498698-1.html # bug 833371 +skip-if(B2G) skip-if(asyncPanZoom&&winWidget) load 498698-1.html # bug 833371 asserts(1) load 578604-1.html # bug 584564 asserts(4-7) load 590302-1.xhtml # bug 584564 load 626014.xhtml diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index d5ed1d581acc..42159ee44e35 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -363,7 +363,7 @@ load 496742.html load 499138.html load 499862-1.html load 499857-1.html -asserts-if(winWidget,0-3) load 499885-1.xhtml +asserts-if(winWidget,0-3) skip-if(asyncPanZoom&&winWidget) load 499885-1.xhtml load 501535-1.html load 503961-1.xhtml load 503961-2.html diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index 119a770dcc52..dec4dd337cd4 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -642,6 +642,11 @@ nsBlockReflowState::CanPlaceFloat(nscoord aFloatISize, aFloatISize; } +// Return the inline-size that the float (including margins) will take up +// in the writing mode of the containing block. If this returns +// NS_UNCONSTRAINEDSIZE, we're dealing with an orthogonal block that +// has block-size:auto, and we'll need to actually reflow it to find out +// how much inline-size it will occupy in the containing block's mode. static nscoord FloatMarginISize(const nsHTMLReflowState& aCBReflowState, nscoord aFloatAvailableISize, @@ -663,9 +668,17 @@ FloatMarginISize(const nsHTMLReflowState& aCBReflowState, aFloatOffsetState.ComputedLogicalPadding().Size(wm), nsIFrame::ComputeSizeFlags::eShrinkWrap); - return floatSize.ISize(wm) + - aFloatOffsetState.ComputedLogicalMargin().IStartEnd(wm) + - aFloatOffsetState.ComputedLogicalBorderPadding().IStartEnd(wm); + WritingMode cbwm = aCBReflowState.GetWritingMode(); + nscoord floatISize = floatSize.ConvertTo(cbwm, wm).ISize(cbwm); + if (floatISize == NS_UNCONSTRAINEDSIZE) { + return NS_UNCONSTRAINEDSIZE; // reflow is needed to get the true size + } + + return floatISize + + aFloatOffsetState.ComputedLogicalMargin().Size(wm). + ConvertTo(cbwm, wm).ISize(cbwm) + + aFloatOffsetState.ComputedLogicalBorderPadding().Size(wm). + ConvertTo(cbwm, wm).ISize(cbwm); } bool @@ -721,14 +734,20 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat) // If it's a floating first-letter, we need to reflow it before we // know how wide it is (since we don't compute which letters are part // of the first letter until reflow!). - bool isLetter = aFloat->GetType() == nsGkAtoms::letterFrame; - if (isLetter) { + // We also need to do this early reflow if FloatMarginISize returned + // an unconstrained inline-size, which can occur if the float had an + // orthogonal writing mode and 'auto' block-size (in its mode). + bool earlyFloatReflow = + aFloat->GetType() == nsGkAtoms::letterFrame || + floatMarginISize == NS_UNCONSTRAINEDSIZE; + if (earlyFloatReflow) { mBlock->ReflowFloat(*this, adjustedAvailableSpace, aFloat, floatMargin, floatOffsets, false, reflowStatus); floatMarginISize = aFloat->ISize(wm) + floatMargin.IStartEnd(wm); NS_ASSERTION(NS_FRAME_IS_COMPLETE(reflowStatus), - "letter frames shouldn't break, and if they do now, " - "then they're breaking at the wrong point"); + "letter frames and orthogonal floats with auto block-size " + "shouldn't break, and if they do now, then they're breaking " + "at the wrong point"); } // Find a place to place the float. The CSS2 spec doesn't want @@ -853,7 +872,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat) // Reflow the float after computing its vertical position so it knows // where to break. - if (!isLetter) { + if (!earlyFloatReflow) { bool pushedDown = mBCoord != saveBCoord; mBlock->ReflowFloat(*this, adjustedAvailableSpace, aFloat, floatMargin, floatOffsets, pushedDown, reflowStatus); diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 3fdde78372aa..ff53ae6e5455 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -510,9 +510,13 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* kid; for (kid = GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) { - // Skip touch caret frame if we do not build caret. - if (!aBuilder->IsBuildingCaret() && kid->GetContent() == mTouchCaretElement) { - continue; + // Skip touch/selection caret frame if we do not build caret. + if (!aBuilder->IsBuildingCaret()) { + if(kid->GetContent() == mTouchCaretElement || + kid->GetContent() == mSelectionCaretsStartElement|| + kid->GetContent() == mSelectionCaretsEndElement) { + continue; + } } // Put our child into its own pseudo-stack. diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 8fac28601526..438ce726b512 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -16,6 +16,7 @@ #include "mozilla/DebugOnly.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/PathHelpers.h" +#include "gfx2DGlue.h" #include "nsCOMPtr.h" #include "nsFrameList.h" diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 8021d56145ac..2b665c918903 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -2806,16 +2806,28 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty())) * the last repaint. */ void UpdatePaintCountForPaintedPresShells() { - nsTArray * list = PaintedPresShellList(); - for (int i = 0, l = list->Length(); i < l; i++) { - nsCOMPtr shell = do_QueryReferent(list->ElementAt(i)); - + for (nsWeakPtr& item : *PaintedPresShellList()) { + nsCOMPtr shell = do_QueryReferent(item); if (shell) { shell->IncrementPaintCount(); } } } + /** + * @return true if we painted @aShell during the last repaint. + */ + bool DidPaintPresShell(nsIPresShell* aShell) + { + for (nsWeakPtr& item : *PaintedPresShellList()) { + nsCOMPtr shell = do_QueryReferent(item); + if (shell == aShell) { + return true; + } + } + return false; + } + /** * Accessors for the absolute containing block. */ diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 648be173ed5e..8c33031caf16 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -614,7 +614,7 @@ nsImageFrame::OnFrameUpdate(imgIRequest* aRequest, const nsIntRect* aRect) ? mImage->GetImageSpaceInvalidationRect(*aRect) : *aRect; - if (layerInvalidRect.IsEqualInterior(nsIntRect::GetMaxSizedIntRect())) { + if (layerInvalidRect.IsEqualInterior(GetMaxSizedIntRect())) { // Invalidate our entire area. InvalidateSelf(nullptr, nullptr); return NS_OK; diff --git a/layout/generic/nsSimplePageSequenceFrame.cpp b/layout/generic/nsSimplePageSequenceFrame.cpp index 2d5dc6111d49..49ed4b1cb6c9 100644 --- a/layout/generic/nsSimplePageSequenceFrame.cpp +++ b/layout/generic/nsSimplePageSequenceFrame.cpp @@ -170,6 +170,32 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; // we're always complete + // Don't do incremental reflow until we've taught tables how to do + // it right in paginated mode. + if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) { + // Return our desired size + SetDesiredSize(aDesiredSize, aReflowState, mSize.width, mSize.height); + aDesiredSize.SetOverflowAreasToDesiredBounds(); + FinishAndStoreOverflow(&aDesiredSize); + + if (GetRect().Width() != aDesiredSize.Width()) { + // Our width is changing; we need to re-center our children (our pages). + for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) { + nsIFrame* child = e.get(); + nsMargin pageCSSMargin = child->GetUsedMargin(); + nscoord centeringMargin = + ComputeCenteringMargin(aReflowState.ComputedWidth(), + child->GetRect().width, + pageCSSMargin); + nscoord newX = pageCSSMargin.left + centeringMargin; + + // Adjust the child's x-position: + child->MovePositionBy(nsPoint(newX - child->GetNormalPosition().x, 0)); + } + } + return; + } + // See if we can get a Print Settings from the Context if (!mPageData->mPrintSettings && aPresContext->Medium() == nsGkAtoms::print) { diff --git a/layout/reftests/abs-pos/reftest.list b/layout/reftests/abs-pos/reftest.list index 4965d8cc932c..778c2432806e 100644 --- a/layout/reftests/abs-pos/reftest.list +++ b/layout/reftests/abs-pos/reftest.list @@ -49,11 +49,11 @@ skip-if((B2G&&browserIsRemote)||Mulet) != table-cell-8.html table-print-1-ref.ht == continuation-positioned-inline-1.html continuation-positioned-inline-ref.html == continuation-positioned-inline-2.html continuation-positioned-inline-ref.html == scrollframe-1.html scrollframe-1-ref.html -skip-if(B2G||Mulet) fuzzy-if(Android,9,185) == scrollframe-2.html scrollframe-2-ref.html #bug 756530 # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) fuzzy-if(Android,9,185) skip-if(asyncPanZoom&&winWidget) == scrollframe-2.html scrollframe-2-ref.html #bug 756530 # Initial mulet triage: parity with B2G/B2G Desktop fuzzy-if(gtk2Widget,1,8) == select-1.html select-1-ref.html fuzzy-if(gtk2Widget,1,8) == select-1-dynamic.html select-1-ref.html == select-2.html select-2-ref.html -fuzzy-if(gtk2Widget,1,19) fuzzy-if(Android||B2G,17,726) == select-3.html select-3-ref.html +fuzzy-if(gtk2Widget,1,19) fuzzy-if(Android||B2G,17,726) skip-if(asyncPanZoom&&winWidget) == select-3.html select-3-ref.html == multi-column-1.html multi-column-1-ref.html == button-1.html button-1-ref.html == button-2.html button-2-ref.html diff --git a/layout/reftests/border-image/reftest.list b/layout/reftests/border-image/reftest.list index 2b0e9f8dde9c..f7b20fde5518 100644 --- a/layout/reftests/border-image/reftest.list +++ b/layout/reftests/border-image/reftest.list @@ -36,7 +36,7 @@ fails-if(Android||B2G) == center-scaling-3.html center-scaling-3-ref.html # Andr == border-image-outset-1c.html border-image-outset-1-ref.html == border-image-nofill-1.html border-image-nofill-1-ref.html == border-image-outset-resize-1.html border-image-outset-resize-1-ref.html -== border-image-outset-move-1.html border-image-outset-move-1-ref.html +skip-if(asyncPanZoom&&winWidget) == border-image-outset-move-1.html border-image-outset-move-1-ref.html == border-image-style-none.html border-image-style-none-ref.html == border-image-style-none-length.html border-image-style-none-length-ref.html == border-image-style-none-auto.html border-image-style-none-auto-ref.html diff --git a/layout/reftests/border-radius/reftest.list b/layout/reftests/border-radius/reftest.list index 16be96de837e..bb13bb644c4d 100644 --- a/layout/reftests/border-radius/reftest.list +++ b/layout/reftests/border-radius/reftest.list @@ -71,7 +71,7 @@ fuzzy-if(azureQuartz,1,3) skip-if(B2G||Mulet) == invalidate-1a.html invalidate-1 fuzzy-if(azureQuartz,1,3) skip-if(B2G||Mulet) == invalidate-1b.html invalidate-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop # test that border-radius is reduced for scrollbars -skip-if(B2G||Mulet) fails-if(Android) == scrollbar-clamping-1.html scrollbar-clamping-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) fails-if(Android) skip-if(asyncPanZoom&&winWidget) == scrollbar-clamping-1.html scrollbar-clamping-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop skip-if(B2G||Mulet) fails-if(Android) == scrollbar-clamping-2.html scrollbar-clamping-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop # Test for bad corner joins. diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index fdffba6edf32..7849e7fe6b28 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -88,7 +88,7 @@ fuzzy-if(gtk2Widget,6,26200) == 28811-2b.html 28811-2-ref.html # Bug 1128229 != 82711-1-ref.html 82711-2-ref.html != 82711-1-ref.html 82711-3-ref.html != 82711-2-ref.html 82711-3-ref.html -== 84400-1.html 84400-1-ref.html +skip-if(asyncPanZoom&&winWidget) == 84400-1.html 84400-1-ref.html == 84400-2.html 84400-2-ref.html == 97777-1.html 97777-1-ref.html == 97777-2.html 97777-2-ref.html @@ -1404,7 +1404,7 @@ skip-if(B2G||Mulet) == 502447-1.html 502447-1-ref.html # Initial mulet triage: p needs-focus fails == 503531-1.html 503531-1-ref.html == 504032-1.html 504032-1-ref.html == 505743-1.html about:blank -skip-if(B2G||Mulet) fuzzy-if(Android,5,2800) == 506481-1.html 506481-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) skip-if(asyncPanZoom&&winWidget) fuzzy-if(Android,5,2800) == 506481-1.html 506481-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop == 507187-1.html 507187-1-ref.html == 507487-1.html 507487-1-ref.html == 507487-2.xhtml 507487-2-ref.xhtml @@ -1417,7 +1417,7 @@ skip-if(B2G||Mulet) == 508816-2.html 508816-2-ref.html # Initial mulet triage: p skip-if((B2G&&browserIsRemote)||Mulet) == 508908-1.xul 508908-1-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop == 508919-1.xhtml 508919-1-ref.xhtml == 509155-1.xhtml 509155-1-ref.xhtml -skip-if(B2G||Mulet) fuzzy-if(Android,5,1656) == 512410.html 512410-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) skip-if(asyncPanZoom&&winWidget) fuzzy-if(Android,5,1656) == 512410.html 512410-ref.html # Initial mulet triage: parity with B2G/B2G Desktop == 512631-1.html 512631-1-ref.html == 513153-1a.html 513153-1-ref.html == 513153-1b.html 513153-1-ref.html @@ -1491,7 +1491,7 @@ random-if(!haveTestPlugin) == 546071-1.html 546071-1-ref.html == 550325-2.html 550325-1-ref.html == 550325-3.html 550325-1-ref.html == 550716-1.html 550716-1-ref.html -skip-if(B2G||Mulet) fuzzy-if(Android&&AndroidVersion>=15,12,300) == 551463-1.html 551463-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) skip-if(asyncPanZoom&&winWidget) fuzzy-if(Android&&AndroidVersion>=15,12,300) == 551463-1.html 551463-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop == 551699-1.html 551699-1-ref.html == 552334-1.html 552334-1-ref.html # Bug 553571 was specific to MS Indic shaping behavior and Win7 font support; @@ -1575,7 +1575,7 @@ random-if(!winWidget) fails-if(winWidget&&!d2d) random-if(winWidget&&d2d) != 574 skip-if(!haveTestPlugin) skip-if(B2G||Mulet) fails-if(Android) == 579808-1.html 579808-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop skip-if(B2G||Mulet) fails-if(Android) random-if(layersGPUAccelerated) == 579985-1.html 579985-1-ref.html # bug 623452 for WinXP; this bug was only for a regression in BasicLayers anyway # Initial mulet triage: parity with B2G/B2G Desktop skip-if(B2G||Mulet) skip-if(Android) == 580160-1.html 580160-1-ref.html # bug 920927 for Android; issues without the test-plugin # Initial mulet triage: parity with B2G/B2G Desktop -HTTP(..) == 580863-1.html 580863-1-ref.html +skip-if(asyncPanZoom&&winWidget) HTTP(..) == 580863-1.html 580863-1-ref.html skip-if(B2G||Mulet) fails-if(Android) random-if(layersGPUAccelerated) == 581317-1.html 581317-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop == 581579-1.html 581579-1-ref.html == 582037-1a.html 582037-1-ref.html @@ -1667,11 +1667,11 @@ random == 637597-1.html 637597-1-ref.html # bug 637597 was never really fixed! fuzzy-if(Android&&AndroidVersion>=15,8,500) == 637852-1.html 637852-1-ref.html fuzzy-if(Android&&AndroidVersion>=15,8,500) == 637852-2.html 637852-2-ref.html fuzzy-if(Android&&AndroidVersion>=15,8,500) == 637852-3.html 637852-3-ref.html -skip-if(B2G||Mulet) == 641770-1.html 641770-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) skip-if(asyncPanZoom&&winWidget) == 641770-1.html 641770-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop == 641856-1.html 641856-1-ref.html == 645491-1.html 645491-1-ref.html == 645768-1.html 645768-1-ref.html -fails-if(layersGPUAccelerated&&cocoaWidget) fails-if(Android&&AndroidVersion<15&&AndroidVersion!=10) == 650228-1.html 650228-1-ref.html # Quartz alpha blending doesn't match GL alpha blending +fails-if(layersGPUAccelerated&&cocoaWidget) fails-if(Android&&AndroidVersion<15&&AndroidVersion!=10) skip-if(asyncPanZoom&&winWidget) == 650228-1.html 650228-1-ref.html # Quartz alpha blending doesn't match GL alpha blending needs-focus == 652301-1a.html 652301-1-ref.html needs-focus == 652301-1b.html 652301-1-ref.html == 652775-1.html 652775-1-ref.html @@ -1756,7 +1756,7 @@ skip-if(B2G||Mulet) fuzzy-if(Android,4,400) == 815593-1.html 815593-1-ref.html # == 816948-1.html 816948-1-ref.html == 817019-1.html about:blank skip-if(B2G||Mulet) == 818276-1.html 818276-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -fuzzy-if(asyncPanZoom,190,27) == 825999.html 825999-ref.html +fuzzy-if(asyncPanZoom&&!winWidget,190,27) skip-if(asyncPanZoom&&winWidget) == 825999.html 825999-ref.html == 827577-1a.html 827577-1-ref.html == 827577-1b.html 827577-1-ref.html == 827799-1.html about:blank @@ -1806,7 +1806,7 @@ fuzzy-if(B2G,1,7) == 942672-1.html 942672-1-ref.html == 961887-1.html 961887-1-ref.html == 961887-2.html 961887-2-ref.html == 961887-3.html 961887-3-ref.html -pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) == 966992-1.html 966992-1-ref.html +pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) skip-if(asyncPanZoom&&winWidget) == 966992-1.html 966992-1-ref.html skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed skip-if(Android) == 966510-2.html 966510-2-ref.html # same as above == 978911-1.svg 978911-1-ref.svg diff --git a/layout/reftests/css-ui-invalid/select/reftest.list b/layout/reftests/css-ui-invalid/select/reftest.list index b7cb284bd7cb..5a3786ced05e 100644 --- a/layout/reftests/css-ui-invalid/select/reftest.list +++ b/layout/reftests/css-ui-invalid/select/reftest.list @@ -10,7 +10,7 @@ needs-focus == select-required-invalid-changed-1.html select-required-ref.html needs-focus == select-required-invalid-changed-2.html select-required-ref.html needs-focus == select-required-valid.html select-required-ref.html needs-focus == select-required-multiple-invalid.html select-required-multiple-ref.html -needs-focus == select-required-multiple-invalid-changed.html select-required-multiple-ref.html +skip-if(asyncPanZoom&&winWidget) needs-focus == select-required-multiple-invalid-changed.html select-required-multiple-ref.html needs-focus == select-required-multiple-valid.html select-required-multiple-ref.html skip-if(B2G||Mulet) fails-if(Android) needs-focus == select-disabled-fieldset-1.html select-fieldset-ref.html # Initial mulet triage: parity with B2G/B2G Desktop skip-if(B2G||Mulet) fails-if(Android) needs-focus == select-disabled-fieldset-2.html select-fieldset-ref.html # Initial mulet triage: parity with B2G/B2G Desktop diff --git a/layout/reftests/css-ui-valid/select/reftest.list b/layout/reftests/css-ui-valid/select/reftest.list index afa457e52b96..e98a98c47924 100644 --- a/layout/reftests/css-ui-valid/select/reftest.list +++ b/layout/reftests/css-ui-valid/select/reftest.list @@ -11,7 +11,7 @@ needs-focus == select-required-valid-changed-1.html select-required-ref.html needs-focus == select-required-valid-changed-2.html select-required-ref.html needs-focus == select-required-multiple-invalid.html select-required-multiple-ref.html needs-focus == select-required-multiple-valid.html select-required-multiple-ref.html -fuzzy(64,4) needs-focus == select-required-multiple-valid-changed.html select-required-multiple-ref.html +fuzzy(64,4) skip-if(asyncPanZoom&&winWidget) needs-focus == select-required-multiple-valid-changed.html select-required-multiple-ref.html fails-if(Android||B2G||Mulet) needs-focus == select-disabled-fieldset-1.html select-fieldset-ref.html # Initial mulet triage: parity with B2G/B2G Desktop fails-if(Android||B2G||Mulet) needs-focus == select-disabled-fieldset-2.html select-fieldset-ref.html # Initial mulet triage: parity with B2G/B2G Desktop needs-focus == select-fieldset-legend.html select-fieldset-legend-ref.html diff --git a/layout/reftests/floats/orthogonal-floats-1-ref.html b/layout/reftests/floats/orthogonal-floats-1-ref.html new file mode 100644 index 000000000000..a5ccc8a3c85e --- /dev/null +++ b/layout/reftests/floats/orthogonal-floats-1-ref.html @@ -0,0 +1,39 @@ + + + + Bug 1141867 - Contiguous right-floating boxes with vertical writing mode + + + + + + + +
+ +
+ +

Test passes if there is a filled green square and no red.

+ + + diff --git a/layout/reftests/floats/orthogonal-floats-1a.html b/layout/reftests/floats/orthogonal-floats-1a.html new file mode 100644 index 000000000000..87aa34da588e --- /dev/null +++ b/layout/reftests/floats/orthogonal-floats-1a.html @@ -0,0 +1,54 @@ + + + + Bug 1141867 - Contiguous right-floating boxes with vertical writing mode + + + + + + + +
abcde
+ +
fghijk
+ +
lmnopq
+ +
rstuv
+ +
wxyz!
+ +
+ +

Test passes if there is a filled green square and no red.

+ + + diff --git a/layout/reftests/floats/orthogonal-floats-1b.html b/layout/reftests/floats/orthogonal-floats-1b.html new file mode 100644 index 000000000000..f4890f32d1ac --- /dev/null +++ b/layout/reftests/floats/orthogonal-floats-1b.html @@ -0,0 +1,54 @@ + + + + Bug 1141867 - Contiguous right-floating boxes with vertical writing mode + + + + + + + +
abcde
+ +
fghijk
+ +
lmnopq
+ +
rstuv
+ +
wxyz!
+ +
+ +

Test passes if there is a filled green square and no red.

+ + + diff --git a/layout/reftests/floats/orthogonal-floats-1c.html b/layout/reftests/floats/orthogonal-floats-1c.html new file mode 100644 index 000000000000..3c447b0ce9ba --- /dev/null +++ b/layout/reftests/floats/orthogonal-floats-1c.html @@ -0,0 +1,56 @@ + + + + Bug 1141867 - Contiguous right-floating boxes with vertical writing mode + + + + + + + +
abcde
+ +
fghij
+ +
klmno
+ +
qrstu
+ +
vwxyz
+ +
+ +

Test passes if there is a filled green square and no red.

+ + + diff --git a/layout/reftests/floats/orthogonal-floats-1d.html b/layout/reftests/floats/orthogonal-floats-1d.html new file mode 100644 index 000000000000..97a22e1a6663 --- /dev/null +++ b/layout/reftests/floats/orthogonal-floats-1d.html @@ -0,0 +1,56 @@ + + + + Bug 1141867 - Contiguous right-floating boxes with vertical writing mode + + + + + + + +
abcde
+ +
fghij
+ +
klmno
+ +
qrstu
+ +
vwxyz
+ +
+ +

Test passes if there is a filled green square and no red.

+ + + diff --git a/layout/reftests/floats/reftest.list b/layout/reftests/floats/reftest.list index c915e365d5ba..5e71e988696f 100644 --- a/layout/reftests/floats/reftest.list +++ b/layout/reftests/floats/reftest.list @@ -35,3 +35,7 @@ fails == 345369-2.html 345369-2-ref.html == float-in-rtl-4b.html float-in-rtl-4-ref.html == float-in-rtl-4c.html float-in-rtl-4-ref.html == float-in-rtl-4d.html float-in-rtl-4-ref.html +fuzzy-if(OSX==1010,26,7) fuzzy-if(Android,16,2) == orthogonal-floats-1a.html orthogonal-floats-1-ref.html +fuzzy-if(OSX==1010,26,7) == orthogonal-floats-1b.html orthogonal-floats-1-ref.html +fuzzy-if(OSX==1010,103,802) fuzzy-if(winWidget,116,700) HTTP(..) == orthogonal-floats-1c.html orthogonal-floats-1-ref.html +fuzzy-if(OSX==1010,103,802) fuzzy-if(winWidget,116,700) HTTP(..) == orthogonal-floats-1d.html orthogonal-floats-1-ref.html diff --git a/layout/reftests/font-inflation/reftest.list b/layout/reftests/font-inflation/reftest.list index a1da16a01a3c..82e79e699222 100644 --- a/layout/reftests/font-inflation/reftest.list +++ b/layout/reftests/font-inflation/reftest.list @@ -37,7 +37,7 @@ test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceE test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == textarea-3.html textarea-3-ref.html test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == css-transform-1.html css-transform-1-ref.html test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == css-transform-2.html css-transform-2-ref.html -skip-if(B2G||Mulet) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == container-with-clamping.html container-with-clamping-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) skip-if(asyncPanZoom&&winWidget) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == container-with-clamping.html container-with-clamping-ref.html # Initial mulet triage: parity with B2G/B2G Desktop test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) load video-1.html test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-min-1.html intrinsic-min-1-ref.html skip-if(B2G||Mulet) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-max-1.html intrinsic-max-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop diff --git a/layout/reftests/forms/fieldset/reftest.list b/layout/reftests/forms/fieldset/reftest.list index 030dd8c7b6f9..f26cccc56d5f 100644 --- a/layout/reftests/forms/fieldset/reftest.list +++ b/layout/reftests/forms/fieldset/reftest.list @@ -5,7 +5,7 @@ == fieldset-scroll-1.html fieldset-scroll-1-ref.html == fieldset-scrolled-1.html fieldset-scrolled-1-ref.html random-if(B2G||Mulet) == fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -fuzzy-if(winWidget&&!layersGPUAccelerated,102,205) == positioned-container-1.html positioned-container-1-ref.html +fuzzy-if(winWidget&&!layersGPUAccelerated,102,205) skip-if(asyncPanZoom&&winWidget) == positioned-container-1.html positioned-container-1-ref.html == relpos-legend-1.html relpos-legend-1-ref.html == relpos-legend-2.html relpos-legend-2-ref.html test-pref(layout.css.sticky.enabled,true) skip-if((B2G&&browserIsRemote)||Mulet) == sticky-legend-1.html sticky-legend-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop diff --git a/layout/reftests/forms/input/text/reftest.list b/layout/reftests/forms/input/text/reftest.list index 70d8a5d0cd89..4cb03717c782 100644 --- a/layout/reftests/forms/input/text/reftest.list +++ b/layout/reftests/forms/input/text/reftest.list @@ -1,5 +1,5 @@ == bounds-1.html bounds-1-ref.html -== size-1.html size-1-ref.html +skip-if(asyncPanZoom&&winWidget) == size-1.html size-1-ref.html skip-if(B2G||Mulet) == size-2.html size-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop HTTP(..) == baseline-1.html baseline-1-ref.html skip-if((B2G&&browserIsRemote)||Mulet) HTTP(..) == centering-1.xul centering-1-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop diff --git a/layout/reftests/forms/placeholder/reftest.list b/layout/reftests/forms/placeholder/reftest.list index 885096ab12a3..80e7a3d16960 100644 --- a/layout/reftests/forms/placeholder/reftest.list +++ b/layout/reftests/forms/placeholder/reftest.list @@ -16,8 +16,8 @@ == placeholder-3.html placeholder-overridden-ref.html == placeholder-4.html placeholder-overridden-ref.html == placeholder-5.html placeholder-visible-ref.html -fuzzy-if(winWidget,160,7) == placeholder-6.html placeholder-overflow-ref.html -skip-if(B2G||Mulet) == placeholder-6-textarea.html placeholder-overflow-textarea-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(asyncPanZoom&&winWidget) == placeholder-6.html placeholder-overflow-ref.html +skip-if(B2G||Mulet) skip-if(asyncPanZoom&&winWidget) == placeholder-6-textarea.html placeholder-overflow-textarea-ref.html # Initial mulet triage: parity with B2G/B2G Desktop # needs-focus == placeholder-7.html placeholder-focus-ref.html # needs-focus == placeholder-8.html placeholder-focus-ref.html # needs-focus == placeholder-9.html placeholder-focus-ref.html diff --git a/layout/reftests/forms/textarea/reftest.list b/layout/reftests/forms/textarea/reftest.list index 866304435f8e..1957f5a935ef 100644 --- a/layout/reftests/forms/textarea/reftest.list +++ b/layout/reftests/forms/textarea/reftest.list @@ -10,5 +10,5 @@ skip-if(B2G||Mulet) fails-if(Android) fails-if(gtk2Widget) != rtl.html no-resize == rtl.html rtl-dynamic-style.html == rtl.html in-dynamic-rtl-doc.html == setvalue-framereconstruction-1.html setvalue-framereconstruction-ref.html -== padding-scrollbar-placement.html padding-scrollbar-placement-ref.html +skip-if(asyncPanZoom&&winWidget) == padding-scrollbar-placement.html padding-scrollbar-placement-ref.html == various-cols.html various-cols-ref.html diff --git a/layout/reftests/image/reftest.list b/layout/reftests/image/reftest.list index f568cd424ac5..4f5954bb7bb5 100644 --- a/layout/reftests/image/reftest.list +++ b/layout/reftests/image/reftest.list @@ -73,7 +73,7 @@ fuzzy(1,1) == image-orientation-generated-content.html?270&flip image-orientat fuzzy(1,1) == image-orientation-background.html?from-image image-orientation-ref.html?0 fuzzy(1,1) == image-orientation-background.html?90&flip image-orientation-ref.html?0 == image-orientation-border-image.html?from-image image-orientation-border-image.html?0 -== image-orientation-border-image.html?90&flip image-orientation-border-image.html?0 +skip-if(asyncPanZoom&&winWidget) == image-orientation-border-image.html?90&flip image-orientation-border-image.html?0 == image-orientation-list-style-image.html?from-image image-orientation-list-style-image.html?0 == image-orientation-list-style-image.html?90&flip image-orientation-list-style-image.html?0 diff --git a/layout/reftests/invalidation/reftest.list b/layout/reftests/invalidation/reftest.list index cc1af3e5ccfb..df3ef58d958e 100644 --- a/layout/reftests/invalidation/reftest.list +++ b/layout/reftests/invalidation/reftest.list @@ -61,6 +61,6 @@ pref(layout.animated-image-layers.enabled,true) random-if(Android||gtk2Widget) = != layer-splitting-2.html about:blank != layer-splitting-3.html about:blank != layer-splitting-4.html about:blank -!= layer-splitting-5.html about:blank -!= layer-splitting-6.html about:blank +skip-if(asyncPanZoom&&winWidget) != layer-splitting-5.html about:blank +skip-if(asyncPanZoom&&winWidget) != layer-splitting-6.html about:blank != layer-splitting-7.html about:blank diff --git a/layout/reftests/layers/reftest.list b/layout/reftests/layers/reftest.list index 44ec2e05bce1..a0a2891e91a5 100644 --- a/layout/reftests/layers/reftest.list +++ b/layout/reftests/layers/reftest.list @@ -1,20 +1,20 @@ == move-to-background-1.html move-to-background-1-ref.html fuzzy-if(cocoaWidget,2,6) random-if(Android&&!browserIsRemote) == component-alpha-exit-1.html component-alpha-exit-1-ref.html # bug 760275 -!= pull-background-1.html about:blank -!= pull-background-2.html about:blank -!= pull-background-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 -!= pull-background-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 +skip-if(asyncPanZoom) != pull-background-1.html about:blank +skip-if(asyncPanZoom) != pull-background-2.html about:blank +skip-if(asyncPanZoom) != pull-background-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 +skip-if(asyncPanZoom) != pull-background-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 skip-if(asyncPanZoom) != pull-background-5.html about:blank # Fails with event regions, bug 1150941 -!= pull-background-6.html about:blank +skip-if(asyncPanZoom) != pull-background-6.html about:blank # The animated-position tests are disabled for intermittent failures / passes, bug 1150941 skip != pull-background-animated-position-1.html about:blank # Fails with event regions skip != pull-background-animated-position-2.html about:blank skip != pull-background-animated-position-3.html about:blank # Fails because PaintedLayer item assignment doesn't recognize overflow:hidden clips skip != pull-background-animated-position-4.html about:blank # Fails because PaintedLayer item assignment and background pulling don't recognize overflow:hidden clips skip != pull-background-animated-position-5.html about:blank # Fails because ownLayer bounds don't anticipate changes of animated contents, but doesn't fail with event regions -skip-if(!asyncPanZoom) != pull-background-displayport-1.html about:blank -skip-if(!asyncPanZoom) != pull-background-displayport-2.html about:blank -skip-if(!asyncPanZoom) != pull-background-displayport-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 -skip-if(!asyncPanZoom) != pull-background-displayport-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 +skip-if(!asyncPanZoom) skip-if(asyncPanZoom) != pull-background-displayport-1.html about:blank +skip-if(!asyncPanZoom) skip-if(asyncPanZoom) != pull-background-displayport-2.html about:blank +skip-if(!asyncPanZoom) skip-if(asyncPanZoom) != pull-background-displayport-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 +skip-if(!asyncPanZoom) skip-if(asyncPanZoom) != pull-background-displayport-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 fails skip-if(!asyncPanZoom) != pull-background-displayport-5.html about:blank # bug 1147673 -skip-if(!asyncPanZoom) != pull-background-displayport-6.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 +skip-if(!asyncPanZoom) skip-if(asyncPanZoom) != pull-background-displayport-6.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 diff --git a/layout/reftests/position-dynamic-changes/relative/reftest.list b/layout/reftests/position-dynamic-changes/relative/reftest.list index 37f12659c068..a06a246cfc3e 100644 --- a/layout/reftests/position-dynamic-changes/relative/reftest.list +++ b/layout/reftests/position-dynamic-changes/relative/reftest.list @@ -1,5 +1,5 @@ -fuzzy-if(cocoaWidget,1,2) fuzzy-if(d2d,47,26) == move-right-bottom.html move-right-bottom-ref.html -fuzzy-if(cocoaWidget,1,2) == move-top-left.html move-top-left-ref.html # Bug 688545 -fuzzy-if(cocoaWidget,1,3) == move-right-bottom-table.html move-right-bottom-table-ref.html -fuzzy-if(cocoaWidget,1,3) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545 +skip-if(asyncPanZoom&&winWidget) fuzzy-if(cocoaWidget,1,2) fuzzy-if(d2d,47,26) == move-right-bottom.html move-right-bottom-ref.html +skip-if(asyncPanZoom&&winWidget) fuzzy-if(cocoaWidget,1,2) == move-top-left.html move-top-left-ref.html # Bug 688545 +skip-if(asyncPanZoom&&winWidget) fuzzy-if(cocoaWidget,1,3) == move-right-bottom-table.html move-right-bottom-table-ref.html +skip-if(asyncPanZoom&&winWidget) fuzzy-if(cocoaWidget,1,3) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545 == percent.html percent-ref.html diff --git a/layout/reftests/printing/reftest.list b/layout/reftests/printing/reftest.list index bca4d7cf9a8f..e6cf46770c58 100644 --- a/layout/reftests/printing/reftest.list +++ b/layout/reftests/printing/reftest.list @@ -32,4 +32,4 @@ skip-if(B2G||Mulet) fuzzy-if(cocoaWidget,1,5000) == 745025-1.html 745025-1-ref.h random-if((B2G&&browserIsRemote)||Mulet) == 960822.html 960822-ref.html # reftest-print doesn't work on B2G (scrollbar difference only) # Initial mulet triage: parity with B2G/B2G Desktop == 966419-1.html 966419-1-ref.html == 966419-2.html 966419-2-ref.html -# skip-if(B2G||Mulet) asserts(3) HTTP(..) == 1108104.html 1108104-ref.html # bug 1067755, 1135556 # Initial mulet triage: parity with B2G/B2G Desktop +# skip-if(B2G||Mulet) asserts(3) HTTP(..) fails 1108104.html 1108104-ref.html # bug 1067755, 1135556 # Initial mulet triage: parity with B2G/B2G Desktop diff --git a/layout/reftests/reftest.list b/layout/reftests/reftest.list index dd6adb8fa1ed..5a11f152386a 100644 --- a/layout/reftests/reftest.list +++ b/layout/reftests/reftest.list @@ -19,7 +19,7 @@ include w3c-css/received/reftest.list include abs-pos/reftest.list include position-relative/reftest.list -include async-scrolling/reftest.list +skip-if(asyncPanZoom&&winWidget) include async-scrolling/reftest.list # backgrounds/ include backgrounds/reftest.list diff --git a/layout/reftests/scrolling/reftest.list b/layout/reftests/scrolling/reftest.list index d57cd1e8f694..2e9367a66bf4 100644 --- a/layout/reftests/scrolling/reftest.list +++ b/layout/reftests/scrolling/reftest.list @@ -15,7 +15,7 @@ skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.s skip-if(Mulet) skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-3.html scroll-behavior-3.html?ref # see bug 1041833 # MULET: Bug 1144079: Re-enable Mulet mochitests and reftests taskcluster-specific disables skip-if(Mulet) skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-4.html scroll-behavior-4.html?ref # see bug 1041833 # MULET: Bug 1144079: Re-enable Mulet mochitests and reftests taskcluster-specific disables skip-if(Mulet) skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-5.html scroll-behavior-5.html?ref # see bug 1041833 # MULET: Bug 1144079: Re-enable Mulet mochitests and reftests taskcluster-specific disables -skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-6.html scroll-behavior-6.html?ref # see bug 1041833 +skip-if(Android) skip-if(asyncPanZoom&&winWidget) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-6.html scroll-behavior-6.html?ref # see bug 1041833 skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-7.html scroll-behavior-7.html?ref # see bug 1041833 skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-8.html scroll-behavior-8.html?ref # see bug 1041833 skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-9.html scroll-behavior-9.html?ref # see bug 1041833 @@ -27,11 +27,11 @@ skip-if(B2G||Mulet) fuzzy-if(Android&&AndroidVersion<15,251,722) fuzzy-if(d2d,1, HTTP == transformed-1.html?up transformed-1.html?ref fuzzy-if(Android,5,20000) == uncovering-1.html uncovering-1-ref.html fuzzy-if(Android,5,20000) == uncovering-2.html uncovering-2-ref.html -skip-if(B2G||Mulet) == less-than-scrollbar-height.html less-than-scrollbar-height-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) skip-if(asyncPanZoom&&winWidget) == less-than-scrollbar-height.html less-than-scrollbar-height-ref.html # Initial mulet triage: parity with B2G/B2G Desktop skip-if(B2G||Mulet) == huge-horizontal-overflow.html huge-horizontal-overflow-ref.html # Initial mulet triage: parity with B2G/B2G Desktop skip-if(B2G||Mulet) == huge-vertical-overflow.html huge-vertical-overflow-ref.html # Initial mulet triage: parity with B2G/B2G Desktop == iframe-scrolling-attr-1.html iframe-scrolling-attr-ref.html skip-if((B2G&&browserIsRemote)||Mulet) == iframe-scrolling-attr-2.html iframe-scrolling-attr-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -== frame-scrolling-attr-1.html frame-scrolling-attr-ref.html -== frame-scrolling-attr-2.html frame-scrolling-attr-ref.html +skip-if(asyncPanZoom&&winWidget) == frame-scrolling-attr-1.html frame-scrolling-attr-ref.html +skip-if(asyncPanZoom&&winWidget) == frame-scrolling-attr-2.html frame-scrolling-attr-ref.html == move-item.html move-item-ref.html # bug 1125750 diff --git a/layout/reftests/text-overflow/reftest.list b/layout/reftests/text-overflow/reftest.list index 6011cdc6a64c..d09b1cb2b663 100644 --- a/layout/reftests/text-overflow/reftest.list +++ b/layout/reftests/text-overflow/reftest.list @@ -22,5 +22,5 @@ skip-if(B2G||Mulet) HTTP(..) == table-cell.html table-cell-ref.html # Initial mu skip-if(Mulet) HTTP(..) == two-value-syntax.html two-value-syntax-ref.html # MULET: Bug 1144079: Re-enable Mulet mochitests and reftests taskcluster-specific disables skip-if(B2G||Mulet) HTTP(..) == single-value.html single-value-ref.html # Initial mulet triage: parity with B2G/B2G Desktop skip-if(B2G||Mulet) HTTP(..) == atomic-under-marker.html atomic-under-marker-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -fuzzy(1,702) skip-if(Android||B2G||Mulet) HTTP(..) == xulscroll.html xulscroll-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +fuzzy(1,702) skip-if(Android||B2G||Mulet) skip-if(asyncPanZoom&&winWidget) HTTP(..) == xulscroll.html xulscroll-ref.html # Initial mulet triage: parity with B2G/B2G Desktop HTTP(..) == combobox-zoom.html combobox-zoom-ref.html diff --git a/layout/style/ua.css b/layout/style/ua.css index a28132d46243..133e8147b752 100644 --- a/layout/style/ua.css +++ b/layout/style/ua.css @@ -318,11 +318,16 @@ div:-moz-native-anonymous.moz-touchcaret, div:-moz-native-anonymous.moz-selectioncaret-left, div:-moz-native-anonymous.moz-selectioncaret-right { position: fixed; + width: 44px; + height: 47px; } div:-moz-native-anonymous.moz-selectioncaret-left > div, div:-moz-native-anonymous.moz-selectioncaret-right > div { position: absolute; + width: 100%; + height: 100%; + bottom: 0; } div:-moz-native-anonymous.moz-touchcaret, @@ -330,10 +335,9 @@ div:-moz-native-anonymous.moz-selectioncaret-left, div:-moz-native-anonymous.moz-selectioncaret-right, div:-moz-native-anonymous.moz-selectioncaret-left > div, div:-moz-native-anonymous.moz-selectioncaret-right > div { - width: 44px; - height: 47px; - background-position: center center; - background-size: 100% 100%; + background-position: center bottom; + background-size: 100%; + background-repeat: no-repeat; z-index: 2147483647; } diff --git a/layout/svg/nsCSSFilterInstance.cpp b/layout/svg/nsCSSFilterInstance.cpp index 8d541c4112d6..37c3ef238133 100644 --- a/layout/svg/nsCSSFilterInstance.cpp +++ b/layout/svg/nsCSSFilterInstance.cpp @@ -385,14 +385,14 @@ nsCSSFilterInstance::SetBounds(FilterPrimitiveDescription& aDescr, { int32_t inputIndex = GetLastResultIndex(aPrimitiveDescrs); nsIntRect inputBounds = (inputIndex < 0) ? - mTargetBBoxInFilterSpace : ThebesIntRect(aPrimitiveDescrs[inputIndex].PrimitiveSubregion()); + mTargetBBoxInFilterSpace : aPrimitiveDescrs[inputIndex].PrimitiveSubregion(); nsTArray inputExtents; inputExtents.AppendElement(inputBounds); nsIntRegion outputExtents = FilterSupport::PostFilterExtentsForPrimitive(aDescr, inputExtents); - IntRect outputBounds = ToIntRect(outputExtents.GetBounds()); + IntRect outputBounds = outputExtents.GetBounds(); aDescr.SetPrimitiveSubregion(outputBounds); aDescr.SetFilterSpaceBounds(outputBounds); diff --git a/layout/svg/nsFilterInstance.cpp b/layout/svg/nsFilterInstance.cpp index 60a9dd2d9a01..ede860b8a487 100644 --- a/layout/svg/nsFilterInstance.cpp +++ b/layout/svg/nsFilterInstance.cpp @@ -383,7 +383,7 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource, } aSource->mSourceSurface = offscreenDT->Snapshot(); - aSource->mSurfaceRect = ToIntRect(neededRect); + aSource->mSurfaceRect = neededRect; return NS_OK; } @@ -451,7 +451,7 @@ nsFilterInstance::BuildSourceImage(DrawTarget* aTargetDT) mPaintCallback->Paint(*ctx, mTargetFrame, mPaintTransform, &dirty); mSourceGraphic.mSourceSurface = offscreenDT->Snapshot(); - mSourceGraphic.mSurfaceRect = ToIntRect(neededRect); + mSourceGraphic.mSurfaceRect = neededRect; return NS_OK; } @@ -529,7 +529,7 @@ nsFilterInstance::OutputFilterSpaceBounds() const return nsIntRect(); nsIntRect bounds = - ThebesIntRect(mPrimitiveDescriptions[numPrimitives - 1].PrimitiveSubregion()); + mPrimitiveDescriptions[numPrimitives - 1].PrimitiveSubregion(); bool overflow; gfxIntSize surfaceSize = nsSVGUtils::ConvertToSurfaceSize(bounds.Size(), &overflow); diff --git a/layout/svg/nsISVGChildFrame.h b/layout/svg/nsISVGChildFrame.h index 3bc59a1632e4..380a58612f27 100644 --- a/layout/svg/nsISVGChildFrame.h +++ b/layout/svg/nsISVGChildFrame.h @@ -16,7 +16,6 @@ class SVGBBox; struct nsPoint; struct nsRect; -struct nsIntRect; namespace mozilla { class SVGAnimatedLengthList; diff --git a/layout/svg/nsSVGContainerFrame.h b/layout/svg/nsSVGContainerFrame.h index 567a65e688f6..759a61db41b0 100644 --- a/layout/svg/nsSVGContainerFrame.h +++ b/layout/svg/nsSVGContainerFrame.h @@ -23,7 +23,6 @@ class nsStyleContext; struct nsPoint; struct nsRect; -struct nsIntRect; typedef nsContainerFrame nsSVGContainerFrameBase; diff --git a/layout/svg/nsSVGFilterInstance.cpp b/layout/svg/nsSVGFilterInstance.cpp index 0124753db011..00eb53f7a29d 100644 --- a/layout/svg/nsSVGFilterInstance.cpp +++ b/layout/svg/nsSVGFilterInstance.cpp @@ -230,13 +230,13 @@ nsSVGFilterInstance::ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement, int32_t inputIndex = aInputIndices[i]; bool isStandardInput = inputIndex < 0 || inputIndex == mSourceGraphicIndex; IntRect inputSubregion = isStandardInput ? - ToIntRect(mFilterSpaceBounds) : + mFilterSpaceBounds : aPrimitiveDescrs[inputIndex].PrimitiveSubregion(); defaultFilterSubregion = defaultFilterSubregion.Union(inputSubregion); } } else { - defaultFilterSubregion = ToIntRect(mFilterSpaceBounds); + defaultFilterSubregion = mFilterSpaceBounds; } gfxRect feArea = nsSVGUtils::GetRelativeRect(mPrimitiveUnits, @@ -368,7 +368,7 @@ nsSVGFilterInstance::BuildPrimitives(nsTArray& aPrim // Clip previous filter's output to this filter's filter region. if (mSourceGraphicIndex >= 0) { FilterPrimitiveDescription& sourceDescr = aPrimitiveDescrs[mSourceGraphicIndex]; - sourceDescr.SetPrimitiveSubregion(sourceDescr.PrimitiveSubregion().Intersect(ToIntRect(mFilterSpaceBounds))); + sourceDescr.SetPrimitiveSubregion(sourceDescr.PrimitiveSubregion().Intersect(mFilterSpaceBounds)); } // Get the filter primitive elements. @@ -410,7 +410,7 @@ nsSVGFilterInstance::BuildPrimitives(nsTArray& aPrim filter->GetPrimitiveDescription(this, primitiveSubregion, sourcesAreTainted, aInputImages); descr.SetIsTainted(filter->OutputIsTainted(sourcesAreTainted, principal)); - descr.SetFilterSpaceBounds(ToIntRect(mFilterSpaceBounds)); + descr.SetFilterSpaceBounds(mFilterSpaceBounds); descr.SetPrimitiveSubregion(primitiveSubregion.Intersect(descr.FilterSpaceBounds())); for (uint32_t i = 0; i < sourceIndices.Length(); i++) { diff --git a/layout/svg/nsSVGFilterPaintCallback.h b/layout/svg/nsSVGFilterPaintCallback.h index 370e3cf2cc87..3320507c87ab 100644 --- a/layout/svg/nsSVGFilterPaintCallback.h +++ b/layout/svg/nsSVGFilterPaintCallback.h @@ -6,11 +6,11 @@ #ifndef __NS_SVGFILTERPAINTCALLBACK_H__ #define __NS_SVGFILTERPAINTCALLBACK_H__ +#include "nsRect.h" + class nsIFrame; class gfxContext; -struct nsIntRect; - class nsSVGFilterPaintCallback { public: /** diff --git a/layout/svg/nsSVGImageFrame.cpp b/layout/svg/nsSVGImageFrame.cpp index fb48f4388c93..22ab25516fa5 100644 --- a/layout/svg/nsSVGImageFrame.cpp +++ b/layout/svg/nsSVGImageFrame.cpp @@ -349,7 +349,7 @@ nsSVGImageFrame::PaintSVG(gfxContext& aContext, NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() || (mState & NS_FRAME_IS_NONDISPLAY), "Display lists handle dirty rect intersection test"); - dirtyRect = aDirtyRect->ToAppUnits(appUnitsPerDevPx); + dirtyRect = ToAppUnits(*aDirtyRect, appUnitsPerDevPx); // Adjust dirtyRect to match our local coordinate system. nsRect rootRect = nsSVGUtils::TransformFrameRectToOuterSVG(mRect, aTransform, diff --git a/layout/svg/nsSVGIntegrationUtils.h b/layout/svg/nsSVGIntegrationUtils.h index 5a2a4fe8799c..43a746f499e3 100644 --- a/layout/svg/nsSVGIntegrationUtils.h +++ b/layout/svg/nsSVGIntegrationUtils.h @@ -19,7 +19,6 @@ class nsIFrame; class nsIntRegion; struct nsRect; -struct nsIntRect; namespace mozilla { namespace gfx { diff --git a/layout/svg/nsSVGPathGeometryFrame.h b/layout/svg/nsSVGPathGeometryFrame.h index 9cd1af9e45fa..6f293f23626d 100644 --- a/layout/svg/nsSVGPathGeometryFrame.h +++ b/layout/svg/nsSVGPathGeometryFrame.h @@ -32,7 +32,6 @@ class nsSVGMarkerProperty; struct nsPoint; struct nsRect; -struct nsIntRect; typedef nsFrame nsSVGPathGeometryFrameBase; diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index c8d2b270c5a0..6d2d50e13857 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -49,7 +49,6 @@ class gfxTextContextPaint; struct nsStyleSVG; struct nsStyleSVGPaint; struct nsRect; -struct nsIntRect; struct nsPoint; namespace mozilla { diff --git a/layout/tables/nsCellMap.h b/layout/tables/nsCellMap.h index 5751de5a43d1..333892305061 100644 --- a/layout/tables/nsCellMap.h +++ b/layout/tables/nsCellMap.h @@ -12,6 +12,7 @@ #include "nsCOMPtr.h" #include "nsAlgorithm.h" #include "nsAutoPtr.h" +#include "nsRect.h" #include #undef DEBUG_TABLE_CELLMAP @@ -24,7 +25,6 @@ class nsTableFrame; class nsCellMap; class nsPresContext; class nsCellMapColumnIterator; -struct nsIntRect; struct nsColInfo { diff --git a/layout/tables/nsTableOuterFrame.cpp b/layout/tables/nsTableOuterFrame.cpp index 460ab7abb7dc..f29b06e354d7 100644 --- a/layout/tables/nsTableOuterFrame.cpp +++ b/layout/tables/nsTableOuterFrame.cpp @@ -872,25 +872,6 @@ nsTableOuterFrame::Reflow(nsPresContext* aPresContext, innerRS, aOuterRS.ComputedSize(wm).ISize(wm)); } - // Don't do incremental reflow until we've taught tables how to do - // it right in paginated mode. - if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW) && - aPresContext->IsPaginated() && - GetNextInFlow()) { - nsIFrame* nif = GetNextInFlow(); - bool oc = nif->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER; - NS_MergeReflowStatusInto(&aStatus, - oc ? NS_FRAME_OVERFLOW_INCOMPLETE : NS_FRAME_NOT_COMPLETE); - nsMargin innerMargin = innerRS->ComputedPhysicalMargin(); - nsMargin captionMargin; - if (mCaptionFrames.NotEmpty()) { - captionMargin = captionRS->ComputedPhysicalMargin(); - } - UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, captionMargin); - FinishAndStoreOverflow(&aDesiredSize); - return; - } - // First reflow the caption. Maybe captionMet; nsSize captionSize; diff --git a/layout/xul/BoxObject.h b/layout/xul/BoxObject.h index c22705dd4688..1f7a7113e4e4 100644 --- a/layout/xul/BoxObject.h +++ b/layout/xul/BoxObject.h @@ -17,10 +17,10 @@ #include "nsInterfaceHashtable.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" +#include "nsRect.h" class nsIFrame; class nsIDocShell; -struct nsIntRect; class nsIPresShell; namespace mozilla { diff --git a/layout/xul/PopupBoxObject.cpp b/layout/xul/PopupBoxObject.cpp index 56c657722e00..04a76360ef22 100644 --- a/layout/xul/PopupBoxObject.cpp +++ b/layout/xul/PopupBoxObject.cpp @@ -271,7 +271,7 @@ PopupBoxObject::GetOuterScreenRect() widget->GetScreenBounds(screenRect); int32_t pp = menuPopupFrame->PresContext()->AppUnitsPerDevPixel(); - rect->SetLayoutRect(screenRect.ToAppUnits(pp)); + rect->SetLayoutRect(ToAppUnits(screenRect, pp)); } } return rect.forget(); diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp index d1a8db4990d5..9c00ebe6ffe3 100644 --- a/layout/xul/nsMenuPopupFrame.cpp +++ b/layout/xul/nsMenuPopupFrame.cpp @@ -1499,7 +1499,7 @@ nsMenuPopupFrame::GetConstraintRect(const nsRect& aAnchorRect, } } - nsRect screenRect = screenRectPixels.ToAppUnits(presContext->AppUnitsPerDevPixel()); + nsRect screenRect = ToAppUnits(screenRectPixels, presContext->AppUnitsPerDevPixel()); if (mInContentShell) { // for content shells, clip to the client area rather than the screen area screenRect.IntersectRect(screenRect, aRootScreenRect); diff --git a/layout/xul/nsResizerFrame.cpp b/layout/xul/nsResizerFrame.cpp index 4c72e9d3bfa4..ea353a7be0f0 100644 --- a/layout/xul/nsResizerFrame.cpp +++ b/layout/xul/nsResizerFrame.cpp @@ -238,7 +238,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, // direction, don't allow the new size to be less that the resizer's // size. This ensures that content isn't resized too small as to make // the resizer invisible. - nsRect appUnitsRect = LayoutDevicePixel::ToUntyped(rect).ToAppUnits(aPresContext->AppUnitsPerDevPixel()); + nsRect appUnitsRect = ToAppUnits(LayoutDevicePixel::ToUntyped(rect), aPresContext->AppUnitsPerDevPixel()); if (appUnitsRect.width < mRect.width && mouseMove.x) appUnitsRect.width = mRect.width; if (appUnitsRect.height < mRect.height && mouseMove.y) diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index b437f472e069..ce06efc16bb6 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -691,7 +691,7 @@ nsSliderFrame::CurrentPositionChanged() // avoid putting the scroll thumb at subpixel positions which cause needless invalidations nscoord appUnitsPerPixel = PresContext()->AppUnitsPerDevPixel(); - nsRect snappedThumbRect = newThumbRect.ToNearestPixels(appUnitsPerPixel).ToAppUnits(appUnitsPerPixel); + nsRect snappedThumbRect = ToAppUnits(newThumbRect.ToNearestPixels(appUnitsPerPixel), appUnitsPerPixel); if (IsHorizontal()) { newThumbRect.x = snappedThumbRect.x; newThumbRect.width = snappedThumbRect.width; diff --git a/media/mtransport/test/ice_unittest.cpp b/media/mtransport/test/ice_unittest.cpp index b3b7df4bab76..c7124229186c 100644 --- a/media/mtransport/test/ice_unittest.cpp +++ b/media/mtransport/test/ice_unittest.cpp @@ -45,6 +45,10 @@ #include "ice_peer_ctx.h" #include "ice_media_stream.h" +extern "C" { +#include "r_data.h" +} + #define GTEST_HAS_RTTI 0 #include "gtest/gtest.h" #include "gtest_utils.h" @@ -2299,6 +2303,17 @@ TEST_F(PacketFilterTest, TestSendNonRequestStunPacket) { ASSERT_EQ(0, nr_stun_message_destroy(&msg)); } +TEST(InternalsTest, TestAddBogusAttribute) { + nr_stun_message *req; + ASSERT_EQ(0, nr_stun_message_create(&req)); + Data *data; + ASSERT_EQ(0, r_data_alloc(&data, 3000)); + memset(data->data, 'A', data->len); + ASSERT_TRUE(nr_stun_message_add_message_integrity_attribute(req, data)); + ASSERT_EQ(0, r_data_destroy(&data)); + ASSERT_EQ(0, nr_stun_message_destroy(&req)); +} + static std::string get_environment(const char *name) { char *value = getenv(name); diff --git a/media/mtransport/third_party/nICEr/src/stun/stun_msg.c b/media/mtransport/third_party/nICEr/src/stun/stun_msg.c index 1247c3e4ff46..c34bb46b04ef 100644 --- a/media/mtransport/third_party/nICEr/src/stun/stun_msg.c +++ b/media/mtransport/third_party/nICEr/src/stun/stun_msg.c @@ -186,7 +186,9 @@ nr_stun_message_has_attribute(nr_stun_message *msg, UINT2 type, nr_stun_message_ { __code } \ _status=0; \ abort: \ - if (_status) RFREE(attr); \ + if (_status){ \ + nr_stun_message_attribute_destroy(msg, &attr); \ + } \ return(_status); \ } diff --git a/media/webrtc/signaling/src/jsep/JsepCodecDescription.h b/media/webrtc/signaling/src/jsep/JsepCodecDescription.h index 4f14ddf1b261..61ba0f97bdcf 100644 --- a/media/webrtc/signaling/src/jsep/JsepCodecDescription.h +++ b/media/webrtc/signaling/src/jsep/JsepCodecDescription.h @@ -7,7 +7,9 @@ #include #include +#include #include "signaling/src/sdp/SdpMediaSection.h" +#include "nsCRT.h" namespace mozilla { @@ -77,7 +79,7 @@ struct JsepCodecDescription { const SdpRtpmapAttributeList::Rtpmap& entry = rtpmap.GetEntry(fmt); if (mType == remoteMsection.GetMediaType() - && (mName == entry.name) + && !nsCRT::strcasecmp(mName.c_str(), entry.name.c_str()) && (mClock == entry.clock) && (mChannels == entry.channels)) { return ParametersMatch(entry.pt, remoteMsection); @@ -710,7 +712,8 @@ struct JsepApplicationCodecDescription : public JsepCodecDescription { const SdpSctpmapAttributeList::Sctpmap& entry = sctpmap.GetEntry(fmt); - if (mType == remoteMsection.GetMediaType() && (mName == entry.name)) { + if (mType == remoteMsection.GetMediaType() && + !nsCRT::strcasecmp(mName.c_str(), entry.name.c_str())) { return true; } return false; diff --git a/mobile/android/base/Restarter.java b/mobile/android/base/Restarter.java index 464328c0ce47..bb204753e367 100644 --- a/mobile/android/base/Restarter.java +++ b/mobile/android/base/Restarter.java @@ -29,6 +29,7 @@ public class Restarter extends Service { final Intent restartIntent = (Intent)intent.getParcelableExtra(Intent.EXTRA_INTENT); restartIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra("didRestart", true) .setClassName(getApplicationContext(), AppConstants.BROWSER_INTENT_CLASS_NAME); startActivity(restartIntent); diff --git a/mobile/android/base/tests/robocop.ini b/mobile/android/base/tests/robocop.ini index 7a76506f686d..52fd4ea7c785 100644 --- a/mobile/android/base/tests/robocop.ini +++ b/mobile/android/base/tests/robocop.ini @@ -55,6 +55,8 @@ skip-if = android_version == "10" || android_version == "18" [testInputUrlBar] [testJarReader] [testLinkContextMenu] +# disabled on 4.3, bug 1083666 +skip-if = android_version == "18" # [testHomeListsProvider] # see bug 952310 [testHomeProvider] [testLoad] @@ -149,8 +151,8 @@ skip-if = android_version == "10" [testEventDispatcher] [testGeckoRequest] [testInputConnection] -# disabled on Android 2.3; bug 1025968 -skip-if = android_version == "10" +# disabled on Android 2.3, 4.3; bug 1025968 +skip-if = android_version == "10" || android_version == "18" [testJavascriptBridge] [testNativeCrypto] [testReaderModeTitle] diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java index a931daaef677..2f73ce739a9f 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java @@ -18,7 +18,6 @@ import org.mozilla.mozstumbler.service.stumblerthread.blocklist.WifiBlockListInt import org.mozilla.mozstumbler.service.stumblerthread.datahandling.DataStorageManager; import org.mozilla.mozstumbler.service.stumblerthread.scanners.ScanManager; import org.mozilla.mozstumbler.service.uploadthread.UploadAlarmReceiver; -import org.mozilla.mozstumbler.service.utils.NetworkUtils; import org.mozilla.mozstumbler.service.utils.PersistentIntentService; // In stand-alone service mode (a.k.a passive scanning mode), this is created from PassiveServiceReceiver (by calling startService). @@ -118,7 +117,6 @@ public class StumblerService extends PersistentIntentService protected void init() { // Ensure Prefs is created, so internal utility code can use getInstanceWithoutContext Prefs.getInstance(this); - NetworkUtils.createGlobalInstance(this); DataStorageManager.createGlobalInstance(this, this); mReporter.startup(this); diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/AsyncUploader.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/AsyncUploader.java index 64e4746cddcc..57f337e210ae 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/AsyncUploader.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/AsyncUploader.java @@ -25,7 +25,7 @@ import org.mozilla.mozstumbler.service.utils.NetworkUtils; * An exception is made for AppGlobals.isDebug, a false reading is of no consequence. */ public class AsyncUploader extends AsyncTask { private static final String LOG_TAG = AppGlobals.makeLogTag(AsyncUploader.class.getSimpleName()); - private final UploadSettings mSettings; + private final AsyncUploadArgs mUploadArgs; private final Object mListenerLock = new Object(); private AsyncUploaderListener mListener; private static final AtomicBoolean sIsUploading = new AtomicBoolean(); @@ -36,18 +36,22 @@ public class AsyncUploader extends AsyncTask { public void onUploadProgress(); } - public static class UploadSettings { + public static class AsyncUploadArgs { + public final NetworkUtils mNetworkUtils; public final boolean mShouldIgnoreWifiStatus; public final boolean mUseWifiOnly; - public UploadSettings(boolean shouldIgnoreWifiStatus, boolean useWifiOnly) { + public AsyncUploadArgs(NetworkUtils networkUtils, + boolean shouldIgnoreWifiStatus, + boolean useWifiOnly) { + mNetworkUtils = networkUtils; mShouldIgnoreWifiStatus = shouldIgnoreWifiStatus; mUseWifiOnly = useWifiOnly; } } - public AsyncUploader(UploadSettings settings, AsyncUploaderListener listener) { + public AsyncUploader(AsyncUploadArgs args, AsyncUploaderListener listener) { mListener = listener; - mSettings = settings; + mUploadArgs = args; } public void setNickname(String name) { @@ -146,7 +150,8 @@ public class AsyncUploader extends AsyncTask { long uploadedCells = 0; long uploadedWifis = 0; - if (!mSettings.mShouldIgnoreWifiStatus && mSettings.mUseWifiOnly && !NetworkUtils.getInstance().isWifiAvailable()) { + if (!mUploadArgs.mShouldIgnoreWifiStatus && mUploadArgs.mUseWifiOnly && + mUploadArgs.mNetworkUtils.isWifiAvailable()) { if (AppGlobals.isDebug) { Log.d(LOG_TAG, "not on WiFi, not sending"); } diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java index e0b89cca2b27..d6680a1613f9 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java @@ -40,10 +40,12 @@ public class UploadAlarmReceiver extends BroadcastReceiver { public UploadAlarmService(String name) { super(name); + // makes the service START_NOT_STICKY, that is, the service is not auto-restarted + setIntentRedelivery(false); } public UploadAlarmService() { - super(LOG_TAG); + this(LOG_TAG); } @Override @@ -76,11 +78,14 @@ public class UploadAlarmReceiver extends BroadcastReceiver { } } - if (NetworkUtils.getInstance().isWifiAvailable() && + NetworkUtils networkUtils = new NetworkUtils(this); + if (networkUtils.isWifiAvailable() && !AsyncUploader.isUploading()) { Log.d(LOG_TAG, "Alarm upload(), call AsyncUploader"); - AsyncUploader.UploadSettings settings = - new AsyncUploader.UploadSettings(Prefs.getInstance(this).getWifiScanAlways(), Prefs.getInstance(this).getUseWifiOnly()); + AsyncUploader.AsyncUploadArgs settings = + new AsyncUploader.AsyncUploadArgs(networkUtils, + Prefs.getInstance(this).getWifiScanAlways(), + Prefs.getInstance(this).getUseWifiOnly()); AsyncUploader uploader = new AsyncUploader(settings, null); uploader.setNickname(Prefs.getInstance(this).getNickname()); uploader.execute(); @@ -130,4 +135,4 @@ public class UploadAlarmReceiver extends BroadcastReceiver { Intent startServiceIntent = new Intent(context, UploadAlarmService.class); context.startService(startServiceIntent); } -} \ No newline at end of file +} diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/utils/NetworkUtils.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/utils/NetworkUtils.java index de9bcaa45ac4..b3b33b02a5b8 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/utils/NetworkUtils.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/utils/NetworkUtils.java @@ -14,18 +14,9 @@ public final class NetworkUtils { private static final String LOG_TAG = AppGlobals.makeLogTag(NetworkUtils.class.getSimpleName()); ConnectivityManager mConnectivityManager; - static NetworkUtils sInstance; - /* Created at startup by app, or service, using a context. */ - static public void createGlobalInstance(Context context) { - sInstance = new NetworkUtils(); - sInstance.mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - } - - /* If accessed before singleton instantiation will abort. */ - public static NetworkUtils getInstance() { - assert(sInstance != null); - return sInstance; + public NetworkUtils(Context context) { + mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); } public synchronized boolean isWifiAvailable() { diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index d5902f9dffcc..23281efd5c9d 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -478,10 +478,17 @@ pref("media.video_stats.enabled", true); pref("media.audio_data.enabled", false); // Whether to use async panning and zooming +#ifdef XP_WIN +pref("layers.async-pan-zoom.enabled", true); + +// Workaround a bug where inactive scrollframes test this pref directly. +pref("layout.event-regions.enabled", true); +#else pref("layers.async-pan-zoom.enabled", false); // Whether to enable event region building during painting pref("layout.event-regions.enabled", false); +#endif // APZ preferences. For documentation/details on what these prefs do, check // gfx/layers/apz/src/AsyncPanZoomController.cpp. diff --git a/mozglue/linker/ElfLoader.cpp b/mozglue/linker/ElfLoader.cpp index b25aae073346..fcd31c232af6 100644 --- a/mozglue/linker/ElfLoader.cpp +++ b/mozglue/linker/ElfLoader.cpp @@ -1116,8 +1116,17 @@ SEGVHandler::FinishInitialization() */ void *libc = dlopen("libc.so", RTLD_GLOBAL | RTLD_LAZY); if (libc) { - libc_sigaction = - reinterpret_cast(dlsym(libc, "sigaction")); + /* + * Lollipop bionic only has a small trampoline in sigaction, with the real + * work happening in __sigaction. Divert there instead of sigaction if it exists. + * Bug 1154803 + */ + libc_sigaction = reinterpret_cast(dlsym(libc, "__sigaction")); + + if (!libc_sigaction) { + libc_sigaction = + reinterpret_cast(dlsym(libc, "sigaction")); + } } else #endif { diff --git a/netwerk/protocol/http/nsHttpConnectionInfo.h b/netwerk/protocol/http/nsHttpConnectionInfo.h index 86d9e81f1da5..cf4590f4a4b4 100644 --- a/netwerk/protocol/http/nsHttpConnectionInfo.h +++ b/netwerk/protocol/http/nsHttpConnectionInfo.h @@ -63,6 +63,9 @@ public: const nsCString &GetAuthenticationHost() const { return mAuthenticationHost; } int32_t GetAuthenticationPort() const { return mAuthenticationPort; } + const nsCString &GetOrigin() const { return mAuthenticationHost.IsEmpty() ? mHost : mAuthenticationHost; } + int32_t OriginPort() const { return mAuthenticationHost.IsEmpty() ? mPort : mAuthenticationPort; } + // With overhead rebuilding the hash key. The initial // network interface is empty. So you can reduce one call // if there's no explicit route after ctor. diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index b0663b3dbdc5..d3962846cfa8 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -880,8 +880,8 @@ nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry) NS_SUCCEEDED(rv) && index > 0; --index) { if (info->ProtocolEnabled(index - 1)) { rv = sslSocketControl->JoinConnection(info->VersionString[index - 1], - aOriginalEntry->mConnInfo->GetHost(), - aOriginalEntry->mConnInfo->Port(), + aOriginalEntry->mConnInfo->GetOrigin(), + aOriginalEntry->mConnInfo->OriginPort(), &isJoined); if (NS_SUCCEEDED(rv) && isJoined) { break; diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 083f97055523..f17fa25ded70 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -194,8 +194,16 @@ nsNSSSocketInfo::GetBypassAuthentication(bool* arg) NS_IMETHODIMP nsNSSSocketInfo::SetBypassAuthentication(bool arg) { + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + if (!mFd) { + return NS_ERROR_FAILURE; + } + mBypassAuthentication = arg; - return NS_OK; + return SyncNSSNames(locker); } NS_IMETHODIMP @@ -215,7 +223,25 @@ nsNSSSocketInfo::GetAuthenticationName(nsACString& aAuthenticationName) NS_IMETHODIMP nsNSSSocketInfo::SetAuthenticationName(const nsACString& aAuthenticationName) { - return SetHostName(PromiseFlatCString(aAuthenticationName).get()); + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + if (!mFd) { + return NS_ERROR_FAILURE; + } + + nsCString authenticationName(aAuthenticationName); + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, + ("[%p] nsNSSSocketInfo::SetAuthenticationName change from %s to %s\n", + mFd, PromiseFlatCString(GetHostName()).get(), + authenticationName.get())); + + nsresult rv = SetHostName(authenticationName.get()); + if (NS_FAILED(rv)) { + return rv; + } + return SyncNSSNames(locker); } NS_IMETHODIMP @@ -227,7 +253,19 @@ nsNSSSocketInfo::GetAuthenticationPort(int32_t* aAuthenticationPort) NS_IMETHODIMP nsNSSSocketInfo::SetAuthenticationPort(int32_t aAuthenticationPort) { - return SetPort(aAuthenticationPort); + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + if (!mFd) { + return NS_ERROR_FAILURE; + } + + nsresult rv = SetPort(aAuthenticationPort); + if (NS_FAILED(rv)) { + return rv; + } + return SyncNSSNames(locker); } NS_IMETHODIMP @@ -266,6 +304,36 @@ nsNSSSocketInfo::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) return NS_OK; } +// forward declare this for SyncNSSNames() +static nsresult +nsSSLIOLayerSetPeerName(PRFileDesc* fd, nsNSSSocketInfo* infoObject, + const char* host, int32_t port, + const nsNSSShutDownPreventionLock& /* proofOfLock */); + +nsresult +nsNSSSocketInfo::SyncNSSNames(const nsNSSShutDownPreventionLock& proofOfLock) +{ + // I don't know why any of these calls would fail, but if they do + // we need to call SetCanceled to avoid non-determinstic results + + const char* hostName = GetHostNameRaw(); + if (SECSuccess != SSL_SetURL(mFd, hostName)) { + PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("[%p] SyncNSSNames SSL_SetURL error: %d\n", + (void*) mFd, PR_GetError())); + SetCanceled(PR_INVALID_STATE_ERROR, PlainErrorMessage); + return NS_ERROR_FAILURE; + } + + int32_t port = GetPort(); + if (NS_FAILED(nsSSLIOLayerSetPeerName(mFd, this, hostName, port, proofOfLock))) { + PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("[%p] SyncNSSNames SetPeerName error: %d\n", + (void*) mFd, PR_GetError())); + SetCanceled(PR_INVALID_STATE_ERROR, PlainErrorMessage); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + void nsNSSSocketInfo::NoteTimeUntilReady() { @@ -445,6 +513,12 @@ nsNSSSocketInfo::JoinConnection(const nsACString& npnProtocol, if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol)) return NS_OK; + if (mBypassAuthentication) { + // An unauthenticated connection does not know whether or not it + // is acceptable for a particular hostname + return NS_OK; + } + IsAcceptableForHost(hostname, _retval); if (*_retval) { @@ -2520,12 +2594,45 @@ loser: return nullptr; } +static nsresult +nsSSLIOLayerSetPeerName(PRFileDesc* fd, nsNSSSocketInfo* infoObject, + const char* host, int32_t port, + const nsNSSShutDownPreventionLock& /*proofOfLock*/) +{ + // Set the Peer ID so that SSL proxy connections work properly and to + // separate anonymous and/or private browsing connections. + uint32_t flags = infoObject->GetProviderFlags(); + nsAutoCString peerId; + if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080 + peerId.AppendLiteral("anon:"); + } + if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) { + peerId.AppendLiteral("private:"); + } + if (infoObject->GetBypassAuthentication()) { + peerId.AppendLiteral("bypassAuth:"); + } + peerId.Append(host); + peerId.Append(':'); + peerId.AppendInt(port); + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, + ("[%p] nsSSLIOLayerSetPeerName to %s\n", fd, peerId.get())); + if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + static nsresult nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS, const char* proxyHost, const char* host, int32_t port, nsNSSSocketInfo* infoObject) { nsNSSShutDownPreventionLock locker; + if (infoObject->isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + if (forSTARTTLS || proxyHost) { if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) { return NS_ERROR_FAILURE; @@ -2576,24 +2683,7 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS, return NS_ERROR_FAILURE; } - // Set the Peer ID so that SSL proxy connections work properly and to - // separate anonymous and/or private browsing connections. - uint32_t flags = infoObject->GetProviderFlags(); - nsAutoCString peerId; - if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080 - peerId.AppendLiteral("anon:"); - } - if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) { - peerId.AppendLiteral("private:"); - } - peerId.Append(host); - peerId.Append(':'); - peerId.AppendInt(port); - if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) { - return NS_ERROR_FAILURE; - } - - return NS_OK; + return nsSSLIOLayerSetPeerName(fd, infoObject, host, port, locker); } nsresult diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index 4eed0afdb1f6..a4f58339f10e 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -136,6 +136,7 @@ private: bool mPreliminaryHandshakeDone; // after false start items are complete nsresult ActivateSSL(); + nsresult SyncNSSNames(const nsNSSShutDownPreventionLock& proofOfLock); nsCString mNegotiatedNPN; bool mNPNCompleted; diff --git a/security/sandbox/mac/Sandbox.mm b/security/sandbox/mac/Sandbox.mm index 7f3da41cb94b..f283a530cb6b 100644 --- a/security/sandbox/mac/Sandbox.mm +++ b/security/sandbox/mac/Sandbox.mm @@ -243,7 +243,6 @@ static const char contentSandboxRules[] = " (global-name \"com.apple.pasteboard.1\")\n" " (global-name \"com.apple.window_proxies\")\n" " (global-name \"com.apple.windowserver.active\")\n" - " (global-name \"com.apple.cvmsServ\")\n" " (global-name \"com.apple.audio.coreaudiod\")\n" " (global-name \"com.apple.audio.audiohald\")\n" " (global-name \"com.apple.PowerManagement.control\")\n" @@ -262,7 +261,6 @@ static const char contentSandboxRules[] = " (global-name \"com.apple.printtool.daemon\"))\n" "\n" " (allow iokit-open\n" - " (iokit-user-client-class \"AppleGraphicsControlClient\")\n" " (iokit-user-client-class \"IOHIDParamUserClient\")\n" " (iokit-user-client-class \"IOAudioControlUserClient\")\n" " (iokit-user-client-class \"IOAudioEngineUserClient\")\n" @@ -271,8 +269,6 @@ static const char contentSandboxRules[] = " (iokit-user-client-class \"nvSharedUserClient\")\n" " (iokit-user-client-class \"nvFermiGLContext\")\n" " (iokit-user-client-class \"IGAccelGLContext\")\n" - " (iokit-user-client-class \"AGPMClient\")\n" - " (iokit-user-client-class \"IOSurfaceRootUserClient\")\n" " (iokit-user-client-class \"IGAccelSharedUserClient\")\n" " (iokit-user-client-class \"IGAccelVideoContextMain\")\n" " (iokit-user-client-class \"IGAccelVideoContextMedia\")\n" @@ -396,6 +392,21 @@ static const char contentSandboxRules[] = " (appleevent-destination \"com.apple.preview\")\n" " (appleevent-destination \"com.apple.imagecaptureextension2\"))\n" "\n" + "; accelerated graphics\n" + " (allow-shared-preferences-read \"com.apple.opengl\")\n" + " (allow-shared-preferences-read \"com.nvidia.OpenGL\")\n" + " (allow mach-lookup\n" + " (global-name \"com.apple.cvmsServ\"))\n" + " (allow iokit-open\n" + " (iokit-connection \"IOAccelerator\")\n" + " (iokit-user-client-class \"IOAccelerationUserClient\")\n" + " (iokit-user-client-class \"IOSurfaceRootUserClient\")\n" + " (iokit-user-client-class \"IOSurfaceSendRight\")\n" + " (iokit-user-client-class \"IOFramebufferSharedUserClient\")\n" + " (iokit-user-client-class \"AppleSNBFBUserClient\")\n" + " (iokit-user-client-class \"AGPMClient\")\n" + " (iokit-user-client-class \"AppleGraphicsControlClient\")\n" + " (iokit-user-client-class \"AppleGraphicsPolicyClient\"))\n" " )\n" ")\n"; diff --git a/testing/config/mozharness/linux_mulet_config.py b/testing/config/mozharness/linux_mulet_config.py index 0cff4f2e4172..a481e5754359 100644 --- a/testing/config/mozharness/linux_mulet_config.py +++ b/testing/config/mozharness/linux_mulet_config.py @@ -7,6 +7,7 @@ config = { "--appname=%(application)s", "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s", + "--symbols-path=%(symbols_path)s", "--enable-oop", "%(test_manifest)s" ], diff --git a/testing/marionette/client/marionette/b2g_update_test.py b/testing/marionette/client/marionette/b2g_update_test.py index 5c832922e469..3f7c8cfe1327 100644 --- a/testing/marionette/client/marionette/b2g_update_test.py +++ b/testing/marionette/client/marionette/b2g_update_test.py @@ -11,11 +11,11 @@ import time import types import weakref -from b2ginstance import B2GInstance -from marionette_driver.errors import InvalidResponseException from marionette_driver.marionette import Marionette from marionette_test import MarionetteTestCase from marionette_transport import MarionetteTransport + +from b2ginstance import B2GInstance from runtests import MarionetteTestRunner, cli class B2GUpdateMarionetteClient(MarionetteTransport): @@ -237,16 +237,10 @@ class B2GUpdateTestCase(MarionetteTestCase): self.print_status(status, os.path.basename(path)) - try: - results = self.marionette.execute_async_script(data, - script_args=[self.testvars], - special_powers=True) - self.handle_results(path, stage, results) - except InvalidResponseException, e: - # If the update test causes a restart, we will get an invalid - # response from the socket here. - if not will_restart: - raise e + results = self.marionette.execute_async_script(data, + script_args=[self.testvars], + special_powers=True) + self.handle_results(path, stage, results) def handle_results(self, path, stage, results): passed = results['passed'] diff --git a/testing/marionette/client/marionette/marionette_test.py b/testing/marionette/client/marionette/marionette_test.py index a1c56370d4df..bf6ed1f5f2ad 100644 --- a/testing/marionette/client/marionette/marionette_test.py +++ b/testing/marionette/client/marionette/marionette_test.py @@ -16,8 +16,8 @@ import warnings from marionette_driver.errors import ( - MarionetteException, InstallGeckoError, TimeoutException, InvalidResponseException, - JavascriptException, NoSuchElementException, XPathLookupException, NoSuchWindowException, + MarionetteException, TimeoutException, + JavascriptException, NoSuchElementException, NoSuchWindowException, StaleElementException, ScriptTimeoutException, ElementNotVisibleException, NoSuchFrameException, InvalidElementStateException, NoAlertPresentException, InvalidCookieDomainException, UnableToSetCookieException, InvalidSelectorException, diff --git a/testing/marionette/client/marionette/tests/unit/test_errors.py b/testing/marionette/client/marionette/tests/unit/test_errors.py index bcbbded80927..3f3feae44623 100644 --- a/testing/marionette/client/marionette/tests/unit/test_errors.py +++ b/testing/marionette/client/marionette/tests/unit/test_errors.py @@ -74,7 +74,7 @@ class TestLookup(marionette_test.MarionetteTestCase): class TestAllExceptions(marionette_test.MarionetteTestCase): def test_properties(self): - for exc in errors.excs: + for exc in errors.es_: self.assertTrue(hasattr(exc, "code"), "expected exception to have attribute `code'") self.assertTrue(hasattr(exc, "status"), diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js index 00292b526253..0067e7fef8ab 100644 --- a/testing/marionette/driver.js +++ b/testing/marionette/driver.js @@ -155,8 +155,7 @@ ListenerProxy.prototype.__noSuchMethod__ = function*(name, args) { let okListener = () => resolve(); let valListener = msg => resolve(msg.json.value); - let errListener = msg => reject( - "error" in msg.objects ? msg.objects.error : msg.json); + let errListener = msg => reject(msg.objects.error); let handleDialog = function(subject, topic) { listeners.remove(); @@ -2062,7 +2061,7 @@ GeckoDriver.prototype.clickElement = function(cmd, resp) { // listen for it and then just send an error back. The person making the // call should be aware something isnt right and handle accordingly this.addFrameCloseListener("click"); - yield this.listener.clickElement({id: id}); + yield this.listener.clickElement(id); break; } }; @@ -2086,7 +2085,7 @@ GeckoDriver.prototype.getElementAttribute = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementAttribute({id: id, name: name}); + resp.value = yield this.listener.getElementAttribute(id, name); break; } }; @@ -2112,7 +2111,7 @@ GeckoDriver.prototype.getElementText = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementText({id: id}); + resp.value = yield this.listener.getElementText(id); break; } }; @@ -2134,7 +2133,7 @@ GeckoDriver.prototype.getElementTagName = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementTagName({id: id}); + resp.value = yield this.listener.getElementTagName(id); break; } }; @@ -2224,7 +2223,7 @@ GeckoDriver.prototype.isElementEnabled = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.isElementEnabled({id: id}); + resp.value = yield this.listener.isElementEnabled(id); break; } }, @@ -2270,7 +2269,7 @@ GeckoDriver.prototype.getElementSize = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementSize({id: id}); + resp.value = yield this.listener.getElementSize(id); break; } }; @@ -2292,7 +2291,7 @@ GeckoDriver.prototype.getElementRect = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementRect({id: id}); + resp.value = yield this.listener.getElementRect(id); break; } }; diff --git a/testing/marionette/driver/marionette_driver/errors.py b/testing/marionette/driver/marionette_driver/errors.py index 34473cf7d443..a745caecc8b8 100644 --- a/testing/marionette/driver/marionette_driver/errors.py +++ b/testing/marionette/driver/marionette_driver/errors.py @@ -6,6 +6,10 @@ import traceback import types +class InstallGeckoError(Exception): + pass + + class MarionetteException(Exception): """Raised when a generic non-recoverable exception has occured.""" @@ -49,20 +53,22 @@ class MarionetteException(Exception): return "".join(traceback.format_exception(self.__class__, msg, tb)) -class InstallGeckoError(MarionetteException): - pass +class ElementNotSelectableException(MarionetteException): + status = "element not selectable" +class InvalidArgumentException(MarionetteException): + status = "invalid argument" + + +class InvalidSessionIdException(MarionetteException): + status = "invalid session id" + class TimeoutException(MarionetteException): code = (21,) status = "timeout" -class InvalidResponseException(MarionetteException): - code = (53,) - status = "invalid response" - - class JavascriptException(MarionetteException): code = (17,) status = "javascript error" @@ -73,11 +79,6 @@ class NoSuchElementException(MarionetteException): status = "no such element" -class XPathLookupException(MarionetteException): - code = (19,) - status = "invalid xpath selector" - - class NoSuchWindowException(MarionetteException): code = (23,) status = "no such window" @@ -159,11 +160,6 @@ class FrameSendFailureError(MarionetteException): status = "frame send failure" -class UnsupportedOperationException(MarionetteException): - code = (405,) - status = "unsupported operation" - - class SessionNotCreatedException(MarionetteException): code = (33, 71) status = "session not created" @@ -173,50 +169,31 @@ class UnexpectedAlertOpen(MarionetteException): code = (26,) status = "unexpected alert open" -excs = [ - MarionetteException, - TimeoutException, - InvalidResponseException, - JavascriptException, - NoSuchElementException, - XPathLookupException, - NoSuchWindowException, - StaleElementException, - ScriptTimeoutException, - ElementNotVisibleException, - ElementNotAccessibleException, - NoSuchFrameException, - InvalidElementStateException, - NoAlertPresentException, - InvalidCookieDomainException, - UnableToSetCookieException, - InvalidElementCoordinates, - InvalidSelectorException, - MoveTargetOutOfBoundsException, - FrameSendNotInitializedError, - FrameSendFailureError, - UnsupportedOperationException, - SessionNotCreatedException, - UnexpectedAlertOpen, -] + +class UnknownCommandException(MarionetteException): + code = (9,) + status = "unknown command" + + +class UnknownException(MarionetteException): + code = (13,) + status = "unknown error" + + +class UnsupportedOperationException(MarionetteException): + code = (405,) + status = "unsupported operation" + + +es_ = [e for e in locals().values() if type(e) == type and issubclass(e, MarionetteException)] +by_string = {e.status: e for e in es_} +by_number = {c: e for e in es_ for c in e.code} def lookup(identifier): """Finds error exception class by associated Selenium JSON wire protocol number code, or W3C WebDriver protocol string.""" - - by_code = lambda exc: identifier in exc.code - by_status = lambda exc: exc.status == identifier - - rv = None + lookup = by_string if isinstance(identifier, int): - rv = filter(by_code, excs) - elif isinstance(identifier, types.StringTypes): - rv = filter(by_status, excs) - - if not rv: - return MarionetteException - return rv[0] - - -__all__ = excs + ["lookup"] + lookup = by_number + return lookup.get(identifier, MarionetteException) diff --git a/testing/marionette/driver/marionette_driver/geckoinstance.py b/testing/marionette/driver/marionette_driver/geckoinstance.py index 544fed8b255a..7441be6259cd 100644 --- a/testing/marionette/driver/marionette_driver/geckoinstance.py +++ b/testing/marionette/driver/marionette_driver/geckoinstance.py @@ -68,7 +68,6 @@ class GeckoInstance(object): if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: - profile_args["restore"] = False self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path @@ -137,11 +136,12 @@ class GeckoInstance(object): self.runner.cleanup() def restart(self, prefs=None, clean=True): + self.close(restart=True) + if clean: self.profile.cleanup() self.profile = None - self.close(restart=True) if prefs: self.prefs = prefs else: diff --git a/testing/marionette/elements.js b/testing/marionette/elements.js index 884a0f8de1a2..53f13559bba4 100644 --- a/testing/marionette/elements.js +++ b/testing/marionette/elements.js @@ -1,8 +1,11 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +let {utils: Cu} = Components; + +Cu.import("chrome://marionette/content/error.js"); + /** * The ElementManager manages DOM references and interactions with elements. * According to the WebDriver spec (http://code.google.com/p/selenium/wiki/JsonWireProtocol), the @@ -28,8 +31,8 @@ this.EXPORTED_SYMBOLS = [ const DOCUMENT_POSITION_DISCONNECTED = 1; -let uuidGen = Components.classes["@mozilla.org/uuid-generator;1"] - .getService(Components.interfaces.nsIUUIDGenerator); +const uuidGen = Components.classes["@mozilla.org/uuid-generator;1"] + .getService(Components.interfaces.nsIUUIDGenerator); this.CLASS_NAME = "class name"; this.SELECTOR = "css selector"; @@ -42,12 +45,6 @@ this.XPATH = "xpath"; this.ANON= "anon"; this.ANON_ATTRIBUTE = "anon attribute"; -function ElementException(msg, num, stack) { - this.message = msg; - this.code = num; - this.stack = stack; -} - this.Accessibility = function Accessibility() { // A flag indicating whether the accessibility issue should be logged or cause // an exception. Default: log to stdout. @@ -185,7 +182,7 @@ Accessibility.prototype = { return; } if (this.strict) { - throw new ElementException(message, 56, null); + throw new ElementNotAccessibleError(message); } dump(Date.now() + " Marionette: " + message); } @@ -224,19 +221,17 @@ ElementManager.prototype = { let foundEl = null; try { foundEl = this.seenItems[i].get(); - } - catch(e) {} + } catch (e) {} if (foundEl) { if (XPCNativeWrapper(foundEl) == XPCNativeWrapper(element)) { return i; } - } - else { - //cleanup reference to GC'd element + } else { + // cleanup reference to GC'd element delete this.seenItems[i]; } } - var id = uuidGen.generateUUID().toString(); + let id = uuidGen.generateUUID().toString(); this.seenItems[id] = Components.utils.getWeakReference(element); return id; }, @@ -255,7 +250,7 @@ ElementManager.prototype = { getKnownElement: function EM_getKnownElement(id, win) { let el = this.seenItems[id]; if (!el) { - throw new ElementException("Element has not been seen before. Id given was " + id, 17, null); + throw new JavaScriptError("Element has not been seen before. Id given was " + id); } try { el = el.get(); @@ -270,8 +265,9 @@ ElementManager.prototype = { !(XPCNativeWrapper(el).ownerDocument == wrappedWin.document) || (XPCNativeWrapper(el).compareDocumentPosition(wrappedWin.document.documentElement) & DOCUMENT_POSITION_DISCONNECTED)) { - throw new ElementException("The element reference is stale. Either the element " + - "is no longer attached to the DOM or the page has been refreshed.", 10, null); + throw new StaleElementReferenceError( + "The element reference is stale. Either the element " + + "is no longer attached to the DOM or the page has been refreshed."); } return el; }, @@ -369,8 +365,9 @@ ElementManager.prototype = { args.hasOwnProperty(this.w3cElementKey))) { let elementUniqueIdentifier = args[this.w3cElementKey] ? args[this.w3cElementKey] : args[this.elementKey]; converted = this.getKnownElement(elementUniqueIdentifier, win); - if (converted == null) - throw new ElementException("Unknown element: " + elementUniqueIdentifier, 500, null); + if (converted == null) { + throw new WebDriverError(`Unknown element: ${elementUniqueIdentifier}`); + } } else { converted = {}; @@ -443,7 +440,7 @@ ElementManager.prototype = { let startNode = (values.element != undefined) ? this.getKnownElement(values.element, win) : win.document; if (this.elementStrategies.indexOf(values.using) < 0) { - throw new ElementException("No such strategy.", 32, null); + throw new InvalidSelectorError(`No such strategy: ${values.using}`); } let found = all ? this.findElements(values.using, values.value, win.document, startNode) : this.findElement(values.using, values.value, win.document, startNode); @@ -461,7 +458,7 @@ ElementManager.prototype = { } else if (values.using == ANON_ATTRIBUTE) { message = "Unable to locate anonymous element: " + JSON.stringify(values.value); } - on_error({message: message, code: 7}, command_id); + on_error(new NoSuchElementError(message), command_id); } } else { values.time = startTime; @@ -594,7 +591,7 @@ ElementManager.prototype = { element = rootNode.getAnonymousElementByAttribute(startNode, attr, value[attr]); break; default: - throw new ElementException("No such strategy", 500, null); + throw new WebDriverError("No such strategy"); } return element; }, @@ -661,7 +658,7 @@ ElementManager.prototype = { } break; default: - throw new ElementException("No such strategy", 500, null); + throw new WebDriverError("No such strategy"); } return elements; }, diff --git a/testing/marionette/error.js b/testing/marionette/error.js index 9f664fa37260..0a916b420a1e 100644 --- a/testing/marionette/error.js +++ b/testing/marionette/error.js @@ -4,14 +4,17 @@ "use strict"; -const {utils: Cu} = Components; +const {results: Cr, utils: Cu} = Components; const errors = [ + "ElementNotAccessibleError", "ElementNotVisibleError", "FrameSendFailureError", "FrameSendNotInitializedError", "IllegalArgumentError", "InvalidElementStateError", + "InvalidSelectorError", + "InvalidSessionIdError", "JavaScriptError", "NoAlertOpenError", "NoSuchElementError", @@ -19,6 +22,7 @@ const errors = [ "NoSuchWindowError", "ScriptTimeoutError", "SessionNotCreatedError", + "StaleElementReferenceError", "TimeoutError", "UnknownCommandError", "UnknownError", @@ -28,6 +32,26 @@ const errors = [ this.EXPORTED_SYMBOLS = ["error"].concat(errors); +// Because XPCOM is a cesspool of undocumented odd behaviour, +// Object.getPrototypeOf(err) causes another exception if err is an XPCOM +// exception, and cannot be used to determine if err is a prototypal Error. +// +// Consequently we need to check for properties in its prototypal chain +// (using in, instead of err.hasOwnProperty because that causes other +// issues). +// +// Since the input is arbitrary it might _not_ be an Error, and can as +// such be an object with a "result" property without it being considered to +// be an exception. The solution is to build a lookup table of XPCOM +// exceptions from Components.results and check if the value of err#results +// is in that table. +const XPCOM_EXCEPTIONS = []; +{ + for (let prop in Cr) { + XPCOM_EXCEPTIONS.push(Cr[prop]); + } +} + this.error = {}; error.toJSON = function(err) { @@ -38,11 +62,6 @@ error.toJSON = function(err) { }; }; -/** - * Gets WebDriver error by its Selenium status code number. - */ -error.byCode = n => lookup.get(n); - /** * Determines if the given status code is successful. */ @@ -65,18 +84,19 @@ let isOldStyleError = function(obj) { * Prefer using this over using instanceof since the Error prototype * isn't unique across browsers, and XPCOM exceptions are special * snowflakes. + * + * @param {*} val + * Any value that should be undergo the test for errorness. + * @return {boolean} + * True if error, false otherwise. */ -error.isError = function(obj) { - if (obj === null || typeof obj != "object") { +error.isError = function(val) { + if (val === null || typeof val != "object") { return false; - // XPCOM exception. - // Object.getPrototypeOf(obj).result throws error, - // consequently we must do the check for properties in its - // prototypal chain (using in, instead of obj.hasOwnProperty) here. - } else if ("result" in obj) { + } else if ("result" in val && val.result in XPCOM_EXCEPTIONS) { return true; } else { - return Object.getPrototypeOf(obj) == "Error" || isOldStyleError(obj); + return Object.getPrototypeOf(val) == "Error" || isOldStyleError(val); } }; @@ -130,6 +150,14 @@ this.WebDriverError = function(msg) { }; WebDriverError.prototype = Object.create(Error.prototype); +this.ElementNotAccessibleError = function(msg) { + WebDriverError.call(this, msg); + this.name = "ElementNotAccessibleError"; + this.status = "element not accessible"; + this.code = 56; +}; +ElementNotAccessibleError.prototype = Object.create(WebDriverError.prototype); + this.ElementNotVisibleError = function(msg) { WebDriverError.call(this, msg); this.name = "ElementNotVisibleError"; @@ -176,6 +204,22 @@ this.InvalidElementStateError = function(msg) { }; InvalidElementStateError.prototype = Object.create(WebDriverError.prototype); +this.InvalidSelectorError = function(msg) { + WebDriverError.call(this, msg); + this.name = "InvalidSelectorError"; + this.status = "invalid selector"; + this.code = 32; +}; +InvalidSelectorError.prototype = Object.create(WebDriverError.prototype); + +this.InvalidSessionIdError = function(msg) { + WebDriverError.call(this, msg); + this.name = "InvalidSessionIdError"; + this.status = "invalid session id"; + this.code = 13; +}; +InvalidSessionIdError.prototype = Object.create(WebDriverError.prototype); + /** * Creates an error message for a JavaScript error thrown during * executeScript or executeAsyncScript. @@ -270,9 +314,17 @@ this.SessionNotCreatedError = function(msg) { this.status = "session not created"; // should be 33 to match Selenium this.code = 71; -} +}; SessionNotCreatedError.prototype = Object.create(WebDriverError.prototype); +this.StaleElementReferenceError = function(msg) { + WebDriverError.call(this, msg); + this.name = "StaleElementReferenceError"; + this.status = "stale element reference"; + this.code = 10; +}; +StaleElementReferenceError.prototype = Object.create(WebDriverError.prototype); + this.TimeoutError = function(msg) { WebDriverError.call(this, msg); this.name = "TimeoutError"; @@ -304,24 +356,3 @@ this.UnsupportedOperationError = function(msg) { this.code = 405; }; UnsupportedOperationError.prototype = Object.create(WebDriverError.prototype); - -const errorObjs = [ - this.ElementNotVisibleError, - this.FrameSendFailureError, - this.FrameSendNotInitializedError, - this.IllegalArgumentError, - this.InvalidElementStateError, - this.JavaScriptError, - this.NoAlertOpenError, - this.NoSuchElementError, - this.NoSuchFrameError, - this.NoSuchWindowError, - this.ScriptTimeoutError, - this.SessionNotCreatedError, - this.TimeoutError, - this.UnknownCommandError, - this.UnknownError, - this.UnsupportedOperationError, - this.WebDriverError, -]; -const lookup = new Map(errorObjs.map(err => [new err().code, err])); diff --git a/testing/marionette/listener.js b/testing/marionette/listener.js index 33822d5cd4db..53d3ae5a34c3 100644 --- a/testing/marionette/listener.js +++ b/testing/marionette/listener.js @@ -15,6 +15,7 @@ loader.loadSubScript("chrome://marionette/content/simpletest.js"); loader.loadSubScript("chrome://marionette/content/common.js"); loader.loadSubScript("chrome://marionette/content/actions.js"); Cu.import("chrome://marionette/content/elements.js"); +Cu.import("chrome://marionette/content/error.js"); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); @@ -93,7 +94,7 @@ let modalHandler = function() { * If the actor returns an ID, we start the listeners. Otherwise, nothing happens. */ function registerSelf() { - let msg = {value: winUtil.outerWindowID} + let msg = {value: winUtil.outerWindowID}; // register will have the ID and a boolean describing if this is the main process or not let register = sendSyncMessage("Marionette:register", msg); @@ -146,6 +147,28 @@ function emitTouchEventForIFrame(message) { message.force, 90); } +function dispatch(fn) { + return function(msg) { + let id = msg.json.command_id; + try { + let rv; + if (typeof msg.json == "undefined" || msg.json instanceof Array) { + rv = fn.apply(null, msg.json); + } else { + rv = fn(msg.json); + } + + if (typeof rv == "undefined") { + sendOk(id); + } else { + sendResponse({value: rv}, id); + } + } catch (e) { + sendError(e, id); + } + }; +} + /** * Add a message listener that's tied to our listenerId. */ @@ -160,6 +183,15 @@ function removeMessageListenerId(messageName, handler) { removeMessageListener(messageName + listenerId, handler); } +let getElementSizeFn = dispatch(getElementSize); +let getActiveElementFn = dispatch(getActiveElement); +let clickElementFn = dispatch(clickElement); +let getElementAttributeFn = dispatch(getElementAttribute); +let getElementTextFn = dispatch(getElementText); +let getElementTagNameFn = dispatch(getElementTagName); +let getElementRectFn = dispatch(getElementRect); +let isElementEnabledFn = dispatch(isElementEnabled); + /** * Start all message listeners */ @@ -182,17 +214,17 @@ function startListeners() { addMessageListenerId("Marionette:refresh", refresh); addMessageListenerId("Marionette:findElementContent", findElementContent); addMessageListenerId("Marionette:findElementsContent", findElementsContent); - addMessageListenerId("Marionette:getActiveElement", getActiveElement); - addMessageListenerId("Marionette:clickElement", clickElement); - addMessageListenerId("Marionette:getElementAttribute", getElementAttribute); - addMessageListenerId("Marionette:getElementText", getElementText); - addMessageListenerId("Marionette:getElementTagName", getElementTagName); + addMessageListenerId("Marionette:getActiveElement", getActiveElementFn); + addMessageListenerId("Marionette:clickElement", clickElementFn); + addMessageListenerId("Marionette:getElementAttribute", getElementAttributeFn); + addMessageListenerId("Marionette:getElementText", getElementTextFn); + addMessageListenerId("Marionette:getElementTagName", getElementTagNameFn); addMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed); addMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty); addMessageListenerId("Marionette:submitElement", submitElement); - addMessageListenerId("Marionette:getElementSize", getElementSize); - addMessageListenerId("Marionette:getElementRect", getElementRect); - addMessageListenerId("Marionette:isElementEnabled", isElementEnabled); + addMessageListenerId("Marionette:getElementSize", getElementSizeFn); // deprecated + addMessageListenerId("Marionette:getElementRect", getElementRectFn); + addMessageListenerId("Marionette:isElementEnabled", isElementEnabledFn); addMessageListenerId("Marionette:isElementSelected", isElementSelected); addMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement); addMessageListenerId("Marionette:getElementLocation", getElementLocation); //deprecated @@ -287,17 +319,17 @@ function deleteSession(msg) { removeMessageListenerId("Marionette:refresh", refresh); removeMessageListenerId("Marionette:findElementContent", findElementContent); removeMessageListenerId("Marionette:findElementsContent", findElementsContent); - removeMessageListenerId("Marionette:getActiveElement", getActiveElement); - removeMessageListenerId("Marionette:clickElement", clickElement); - removeMessageListenerId("Marionette:getElementAttribute", getElementAttribute); - removeMessageListenerId("Marionette:getElementText", getElementText); - removeMessageListenerId("Marionette:getElementTagName", getElementTagName); + removeMessageListenerId("Marionette:getActiveElement", getActiveElementFn); + removeMessageListenerId("Marionette:clickElement", clickElementFn); + removeMessageListenerId("Marionette:getElementAttribute", getElementAttributeFn); + removeMessageListenerId("Marionette:getElementText", getElementTextFn); + removeMessageListenerId("Marionette:getElementTagName", getElementTagNameFn); removeMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed); removeMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty); removeMessageListenerId("Marionette:submitElement", submitElement); - removeMessageListenerId("Marionette:getElementSize", getElementSize); //deprecated - removeMessageListenerId("Marionette:getElementRect", getElementRect); - removeMessageListenerId("Marionette:isElementEnabled", isElementEnabled); + removeMessageListenerId("Marionette:getElementSize", getElementSizeFn); // deprecated + removeMessageListenerId("Marionette:getElementRect", getElementRectFn); + removeMessageListenerId("Marionette:isElementEnabled", isElementEnabledFn); removeMessageListenerId("Marionette:isElementSelected", isElementSelected); removeMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement); removeMessageListenerId("Marionette:getElementLocation", getElementLocation); @@ -331,40 +363,42 @@ function deleteSession(msg) { /** * Generic method to send a message to the server */ -function sendToServer(msg, value, command_id) { - if (command_id) { - value.command_id = command_id; +function sendToServer(name, data, objs, id) { + if (!data) { + data = {} } - sendAsyncMessage(msg, value); + if (id) { + data.command_id = id; + } + sendAsyncMessage(name, data, objs); } /** * Send response back to server */ function sendResponse(value, command_id) { - sendToServer("Marionette:done", value, command_id); + sendToServer("Marionette:done", value, null, command_id); } /** * Send ack back to server */ function sendOk(command_id) { - sendToServer("Marionette:ok", {}, command_id); + sendToServer("Marionette:ok", null, null, command_id); } /** * Send log message to server */ function sendLog(msg) { - sendToServer("Marionette:log", { message: msg }); + sendToServer("Marionette:log", {message: msg}); } /** * Send error message to server */ -function sendError(msg, code, stack, cmdId) { - let payload = {message: msg, code: code, stack: stack}; - sendToServer("Marionette:error", payload, cmdId); +function sendError(err, cmdId) { + sendToServer("Marionette:error", null, {error: err}, cmdId); } /** @@ -458,8 +492,8 @@ function createExecuteContentSandbox(aWindow, timeout) { }); } - sandbox.asyncComplete = function sandbox_asyncComplete(value, status, stack, commandId) { - if (commandId == asyncTestCommandId) { + sandbox.asyncComplete = function(obj, id) { + if (id == asyncTestCommandId) { curFrame.removeEventListener("unload", onunload, false); curFrame.clearTimeout(asyncTestTimeoutId); @@ -467,24 +501,19 @@ function createExecuteContentSandbox(aWindow, timeout) { curFrame.clearTimeout(inactivityTimeoutId); } - sendSyncMessage("Marionette:shareData", - {log: elementManager.wrapValue(marionetteLogObj.getLogs())}); + {log: elementManager.wrapValue(marionetteLogObj.getLogs())}); marionetteLogObj.clearLogs(); - if (status == 0){ + if (error.isError(obj)) { + sendError(obj, id); + } else { if (Object.keys(_emu_cbs).length) { _emu_cbs = {}; - sendError("Emulator callback still pending when finish() called", - 500, null, commandId); + sendError(new WebDriverError("Emulator callback still pending when finish() called"), id); + } else { + sendResponse({value: elementManager.wrapValue(obj)}, id); } - else { - sendResponse({value: elementManager.wrapValue(value), status: status}, - commandId); - } - } - else { - sendError(value, status, stack, commandId); } asyncTestRunning = false; @@ -495,33 +524,32 @@ function createExecuteContentSandbox(aWindow, timeout) { }; sandbox.finish = function sandbox_finish() { if (asyncTestRunning) { - sandbox.asyncComplete(marionette.generate_results(), 0, null, sandbox.asyncTestCommandId); + sandbox.asyncComplete(marionette.generate_results(), sandbox.asyncTestCommandId); } else { return marionette.generate_results(); } }; - sandbox.marionetteScriptFinished = function sandbox_marionetteScriptFinished(value) { - return sandbox.asyncComplete(value, 0, null, sandbox.asyncTestCommandId); - }; + sandbox.marionetteScriptFinished = val => + sandbox.asyncComplete(val, sandbox.asyncTestCommandId); return sandbox; } /** * Execute the given script either as a function body (executeScript) - * or directly (for 'mochitest' like JS Marionette tests) + * or directly (for mochitest like JS Marionette tests). */ function executeScript(msg, directInject) { // Set up inactivity timeout. if (msg.json.inactivityTimeout) { let setTimer = function() { - inactivityTimeoutId = curFrame.setTimeout(function() { - sendError('timed out due to inactivity', 28, null, asyncTestCommandId); + inactivityTimeoutId = curFrame.setTimeout(function() { + sendError(new ScriptTimeoutError("timed out due to inactivity"), asyncTestCommandId); }, msg.json.inactivityTimeout); }; setTimer(); - heartbeatCallback = function resetInactivityTimeout() { + heartbeatCallback = function() { curFrame.clearTimeout(inactivityTimeoutId); setTimer(); }; @@ -534,11 +562,10 @@ function executeScript(msg, directInject) { sandbox = createExecuteContentSandbox(curFrame, msg.json.timeout); if (!sandbox) { - sendError("Could not create sandbox!", 500, null, asyncTestCommandId); + sendError(new WebDriverError("Could not create sandbox!"), asyncTestCommandId); return; } - } - else { + } else { sandbox.asyncTestCommandId = asyncTestCommandId; } @@ -558,7 +585,7 @@ function executeScript(msg, directInject) { marionetteLogObj.clearLogs(); if (res == undefined || res.passed == undefined) { - sendError("Marionette.finish() not called", 17, null, asyncTestCommandId); + sendError(new JavaScriptError("Marionette.finish() not called"), asyncTestCommandId); } else { sendResponse({value: elementManager.wrapValue(res)}, asyncTestCommandId); @@ -568,9 +595,8 @@ function executeScript(msg, directInject) { try { sandbox.__marionetteParams = Cu.cloneInto(elementManager.convertWrappedArguments( msg.json.args, curFrame), sandbox, { wrapReflectors: true }); - } - catch(e) { - sendError(e.message, e.code, e.stack, asyncTestCommandId); + } catch (e) { + sendError(e, asyncTestCommandId); return; } @@ -590,15 +616,14 @@ function executeScript(msg, directInject) { marionetteLogObj.clearLogs(); sendResponse({value: elementManager.wrapValue(res)}, asyncTestCommandId); } - } - catch (e) { - // 17 = JavascriptException - let error = createStackMessage(e, - "execute_script", - msg.json.filename, - msg.json.line, - script); - sendError(error[0], 17, error[1], asyncTestCommandId); + } catch (e) { + let err = new JavaScriptError( + e, + "execute_script", + msg.json.filename, + msg.json.line, + script); + sendError(err, asyncTestCommandId); } } @@ -642,12 +667,12 @@ function executeWithCallback(msg, useFinish) { if (msg.json.inactivityTimeout) { let setTimer = function() { inactivityTimeoutId = curFrame.setTimeout(function() { - sandbox.asyncComplete('timed out due to inactivity', 28, null, asyncTestCommandId); + sandbox.asyncComplete(new ScriptTimeout("timed out due to inactivity"), asyncTestCommandId); }, msg.json.inactivityTimeout); }; setTimer(); - heartbeatCallback = function resetInactivityTimeout() { + heartbeatCallback = function() { curFrame.clearTimeout(inactivityTimeoutId); setTimer(); }; @@ -657,7 +682,7 @@ function executeWithCallback(msg, useFinish) { asyncTestCommandId = msg.json.command_id; onunload = function() { - sendError("unload was called", 17, null, asyncTestCommandId); + sendError(new JavaScriptError("unload was called"), asyncTestCommandId); }; curFrame.addEventListener("unload", onunload, false); @@ -665,7 +690,7 @@ function executeWithCallback(msg, useFinish) { sandbox = createExecuteContentSandbox(curFrame, msg.json.timeout); if (!sandbox) { - sendError("Could not create sandbox!", 17, null, asyncTestCommandId); + sendError(new JavaScriptError("Could not create sandbox!"), asyncTestCommandId); return; } } @@ -680,19 +705,19 @@ function executeWithCallback(msg, useFinish) { // http://code.google.com/p/selenium/source/browse/trunk/javascript/firefox-driver/js/evaluate.js. // We'll stay compatible with the Selenium code. asyncTestTimeoutId = curFrame.setTimeout(function() { - sandbox.asyncComplete('timed out', 28, null, asyncTestCommandId); + sandbox.asyncComplete(new ScriptTimeoutError("timed out"), asyncTestCommandId); }, msg.json.timeout); originalOnError = curFrame.onerror; - curFrame.onerror = function errHandler(errMsg, url, line) { - sandbox.asyncComplete(errMsg, 17, "@" + url + ", line " + line, asyncTestCommandId); + curFrame.onerror = function errHandler(msg, url, line) { + sandbox.asyncComplete(new JavaScriptError(msg + "@" + url + ", line " + line), asyncTestCommandId); curFrame.onerror = originalOnError; }; let scriptSrc; if (useFinish) { if (msg.json.timeout == null || msg.json.timeout == 0) { - sendError("Please set a timeout", 21, null, asyncTestCommandId); + sendError(new TimeoutError("Please set a timeout"), asyncTestCommandId); } scriptSrc = script; } @@ -700,9 +725,8 @@ function executeWithCallback(msg, useFinish) { try { sandbox.__marionetteParams = Cu.cloneInto(elementManager.convertWrappedArguments( msg.json.args, curFrame), sandbox, { wrapReflectors: true }); - } - catch(e) { - sendError(e.message, e.code, e.stack, asyncTestCommandId); + } catch (e) { + sendError(e, asyncTestCommandId); return; } @@ -723,13 +747,13 @@ function executeWithCallback(msg, useFinish) { } Cu.evalInSandbox(scriptSrc, sandbox, "1.8", "dummy file", 0); } catch (e) { - // 17 = JavascriptException - let error = createStackMessage(e, - "execute_async_script", - msg.json.filename, - msg.json.line, - scriptSrc); - sandbox.asyncComplete(error[0], 17, error[1], asyncTestCommandId); + let err = new JavaScriptError( + e, + "execute_async_script", + msg.json.filename, + msg.json.line, + scriptSrc); + sandbox.asyncComplete(err, asyncTestCommandId); } } @@ -856,7 +880,7 @@ function singleTap(msg) { let visible = checkVisible(el, msg.json.corx, msg.json.cory); checkVisibleAccessibility(acc, visible); if (!visible) { - sendError("Element is not currently visible and may not be manipulated", 11, null, command_id); + sendError(new ElementNotVisibleError("Element is not currently visible and may not be manipulated"), command_id); return; } checkActionableAccessibility(acc); @@ -871,10 +895,9 @@ function singleTap(msg) { emitTouchEvent('touchend', touch); } actions.mouseTap(el.ownerDocument, c.x, c.y); - sendOk(msg.json.command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, msg.json.command_id); + sendOk(command_id); + } catch (e) { + sendError(e, command_id); } } @@ -959,12 +982,8 @@ function actionChain(msg) { let touchId = msg.json.nextId; let callbacks = {}; - callbacks.onSuccess = (value) => { - sendResponse(value, command_id); - }; - callbacks.onError = (message, code, trace) => { - sendError(message, code, trace, msg.json.command_id); - }; + callbacks.onSuccess = value => sendResponse(value, command_id); + callbacks.onError = err => sendError(err, command_id); let touchProvider = {}; touchProvider.createATouch = createATouch; @@ -979,7 +998,7 @@ function actionChain(msg) { callbacks, touchProvider); } catch (e) { - sendError(e.message, e.code, e.stack, command_id); + sendError(e, command_id); } } @@ -1144,9 +1163,8 @@ function multiAction(msg) { // pendingTouches keeps track of current touches that's on the screen let pendingTouches = []; setDispatch(concurrentEvent, pendingTouches, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, msg.json.command_id); + } catch (e) { + sendError(e, command_id); } } @@ -1178,7 +1196,7 @@ function pollForReadyState(msg, start, callback) { !curFrame.document.baseURI.startsWith(url)) { // We have reached an error url without requesting it. callback(); - sendError("Error loading page", 13, null, command_id); + sendError(new UnknownError("Error loading page"), command_id); } else if (curFrame.document.readyState == "interactive" && curFrame.document.baseURI.startsWith("about:")) { callback(); @@ -1186,11 +1204,9 @@ function pollForReadyState(msg, start, callback) { } else { navTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT); } - } - else { + } else { callback(); - sendError("Error loading page, timed out (checkLoad)", 21, null, - command_id); + sendError(new TimeoutError("Error loading page, timed out (checkLoad)"), command_id); } } checkLoad(); @@ -1220,8 +1236,7 @@ function get(msg) { function timerFunc() { removeEventListener("DOMContentLoaded", onDOMContentLoaded, false); - sendError("Error loading page, timed out (onDOMContentLoaded)", 21, - null, msg.json.command_id); + sendError(new TimeoutError("Error loading page, timed out (onDOMContentLoaded)"), msg.json.command_id); } if (msg.json.pageTimeout != null) { navTimer.initWithCallback(timerFunc, msg.json.pageTimeout, Ci.nsITimer.TYPE_ONE_SHOT); @@ -1306,13 +1321,12 @@ function refresh(msg) { function findElementContent(msg) { let command_id = msg.json.command_id; try { - let on_success = function(el, cmd_id) { sendResponse({value: el}, cmd_id) }; - let on_error = function(e, cmd_id) { sendError(e.message, e.code, null, cmd_id); }; + let onSuccess = (el, id) => sendResponse({value: el}, id); + let onError = (err, id) => sendError(err, id); elementManager.find(curFrame, msg.json, msg.json.searchTimeout, - false /* all */, on_success, on_error, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); + false /* all */, onSuccess, onError, command_id); + } catch (e) { + sendError(e, command_id); } } @@ -1322,97 +1336,90 @@ function findElementContent(msg) { function findElementsContent(msg) { let command_id = msg.json.command_id; try { - let on_success = function(els, cmd_id) { sendResponse({value: els}, cmd_id); }; - let on_error = function(e, cmd_id) { sendError(e.message, e.code, null, cmd_id); }; + let onSuccess = (els, id) => sendResponse({value: els}, id); + let onError = (err, id) => sendError(err, id); elementManager.find(curFrame, msg.json, msg.json.searchTimeout, - true /* all */, on_success, on_error, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); + true /* all */, onSuccess, onError, command_id); + } catch (e) { + sendError(e, command_id); } } /** - * Find and return the active element on the page + * Find and return the active element on the page. + * + * @return {WebElement} + * Reference to web element. */ -function getActiveElement(msg) { - let command_id = msg.json.command_id; - var element = curFrame.document.activeElement; - var id = elementManager.addToKnownElements(element); - sendResponse({value: id}, command_id); +function getActiveElement() { + let el = curFrame.document.activeElement; + return elementManager.addToKnownElements(el); } /** - * Send click event to element + * Send click event to element. + * + * @param {WebElement} id + * Reference to the web element to click. */ -function clickElement(msg) { - let command_id = msg.json.command_id; - let el; - try { - el = elementManager.getKnownElement(msg.json.id, curFrame); - let acc = accessibility.getAccessibleObject(el, true); - let visible = checkVisible(el); - checkVisibleAccessibility(acc, visible); - if (visible) { - checkActionableAccessibility(acc); - if (utils.isElementEnabled(el)) { - utils.synthesizeMouseAtCenter(el, {}, el.ownerDocument.defaultView) - } - else { - sendError("Element is not Enabled", 12, null, command_id) - } - } - else { - sendError("Element is not visible", 11, null, command_id) - } - sendOk(command_id); +function clickElement(id) { + let el = elementManager.getKnownElement(id, curFrame); + let acc = accessibility.getAccessibleObject(el, true); + let visible = checkVisible(el); + checkVisibleAccessibility(acc, visible); + if (!visible) { + throw new ElementNotVisibleError("Element is not visible"); } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); + checkActionableAccessibility(acc); + if (utils.isElementEnabled(el)) { + utils.synthesizeMouseAtCenter(el, {}, el.ownerDocument.defaultView); + } else { + throw new InvalidElementStateError("Element is not Enabled"); } } /** - * Get a given attribute of an element + * Get a given attribute of an element. + * + * @param {WebElement} id + * Reference to the web element to get the attribute of. + * @param {string} name + * Name of the attribute. + * + * @return {string} + * The value of the attribute. */ -function getElementAttribute(msg) { - let command_id = msg.json.command_id; - try { - let el = elementManager.getKnownElement(msg.json.id, curFrame); - sendResponse({value: utils.getElementAttribute(el, msg.json.name)}, - command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); - } +function getElementAttribute(id, name) { + let el = elementManager.getKnownElement(id, curFrame); + return utils.getElementAttribute(el, name); } /** * Get the text of this element. This includes text from child elements. + * + * @param {WebElement} id + * Reference to web element. + * + * @return {string} + * Text of element. */ -function getElementText(msg) { - let command_id = msg.json.command_id; - try { - let el = elementManager.getKnownElement(msg.json.id, curFrame); - sendResponse({value: utils.getElementText(el)}, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); - } +function getElementText(id) { + let el = elementManager.getKnownElement(id, curFrame); + return utils.getElementText(el); } /** * Get the tag name of an element. + * + * @param {WebElement} id + * Reference to web element. + * + * @return {string} + * Tag name of element. */ -function getElementTagName(msg) { - let command_id = msg.json.command_id; - try { - let el = elementManager.getKnownElement(msg.json.id, curFrame); - sendResponse({value: el.tagName.toLowerCase()}, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); - } +function getElementTagName(id) { + let el = elementManager.getKnownElement(id, curFrame); + return el.tagName.toLowerCase(); } /** @@ -1425,9 +1432,8 @@ function isElementDisplayed(msg) { let displayed = utils.isElementDisplayed(el); checkVisibleAccessibility(accessibility.getAccessibleObject(el), displayed); sendResponse({value: displayed}, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); + } catch (e) { + sendError(e, command_id); } } @@ -1446,9 +1452,8 @@ function getElementValueOfCssProperty(msg){ let el = elementManager.getKnownElement(msg.json.id, curFrame); sendResponse({value: curFrame.document.defaultView.getComputedStyle(el, null).getPropertyValue(propertyName)}, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); + } catch (e) { + sendError(e, command_id); } } @@ -1467,67 +1472,63 @@ function submitElement (msg) { if (el.tagName && el.tagName.toLowerCase() == 'form') { el.submit(); sendOk(command_id); + } else { + sendError(new NoSuchElementError("Element is not a form element or in a form"), command_id); } - else { - sendError("Element is not a form element or in a form", 7, null, command_id); - } - - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); + } catch (e) { + sendError(e, command_id); } } /** - * Get the size of the element and return it + * Get the size of the element. + * + * @param {WebElement} id + * Web element reference. + * + * @return {Object.} + * The width/height dimensions of th element. */ -function getElementSize(msg){ - let command_id = msg.json.command_id; - try { - let el = elementManager.getKnownElement(msg.json.id, curFrame); - let clientRect = el.getBoundingClientRect(); - sendResponse({value: {width: clientRect.width, height: clientRect.height}}, - command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); - } +function getElementSize(id) { + let el = elementManager.getKnownElement(id, curFrame); + let clientRect = el.getBoundingClientRect(); + return {width: clientRect.width, height: clientRect.height}; } /** - * Get the size of the element and return it + * Get the size of the element. + * + * @param {WebElement} id + * Reference to web element. + * + * @return {Object.} + * The x, y, width, and height properties of the element. */ -function getElementRect(msg){ - let command_id = msg.json.command_id; - try { - let el = elementManager.getKnownElement(msg.json.id, curFrame); - let clientRect = el.getBoundingClientRect(); - sendResponse({value: {x: clientRect.x + curFrame.pageXOffset, - y: clientRect.y + curFrame.pageYOffset, - width: clientRect.width, - height: clientRect.height}}, - command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); - } +function getElementRect(id) { + let el = elementManager.getKnownElement(id, curFrame); + let clientRect = el.getBoundingClientRect(); + return { + x: clientRect.x + curFrame.pageXOffset, + y: clientRect.y + curFrame.pageYOffset, + width: clientRect.width, + height: clientRect.height + }; } /** - * Check if element is enabled + * Check if element is enabled. + * + * @param {WebElement} id + * Reference to web element. + * + * @return {boolean} + * True if enabled, false otherwise. */ -function isElementEnabled(msg) { - let command_id = msg.json.command_id; - try { - let el = elementManager.getKnownElement(msg.json.id, curFrame); - let enabled = utils.isElementEnabled(el); - checkEnabledStateAccessibility(accessibility.getAccessibleObject(el), - enabled); - sendResponse({value: enabled}, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); - } +function isElementEnabled(id) { + let el = elementManager.getKnownElement(id, curFrame); + let enabled = utils.isElementEnabled(el); + checkEnabledStateAccessibility(accessibility.getAccessibleObject(el), enabled); + return enabled; } /** @@ -1538,9 +1539,8 @@ function isElementSelected(msg) { try { let el = elementManager.getKnownElement(msg.json.id, curFrame); sendResponse({value: utils.isElementSelected(el)}, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); + } catch (e) { + sendError(e, command_id); } } @@ -1567,7 +1567,7 @@ function sendKeysToElement(msg) { file = new File(p); } catch (e) { let err = new IllegalArgumentError(`File not found: ${val}`); - sendError(err.message, err.code, err.stack, command_id); + sendError(err, command_id); return; } fs.push(file); @@ -1598,9 +1598,8 @@ function getElementLocation(msg) { location.y = rect.top; sendResponse({value: location}, command_id); - } - catch (e) { - sendError(e.message, e.code, e.stack, command_id); + } catch (e) { + sendError(e, command_id); } } @@ -1618,7 +1617,7 @@ function clearElement(msg) { } sendOk(command_id); } catch (e) { - sendError(e.message, e.code, e.stack, command_id); + sendError(e, command_id); } } @@ -1633,9 +1632,9 @@ function switchToFrame(msg) { if (curFrame.document.readyState == "complete") { sendOk(command_id); return; - } - else if (curFrame.document.readyState == "interactive" && errorRegex.exec(curFrame.document.baseURI)) { - sendError("Error loading page", 13, null, command_id); + } else if (curFrame.document.readyState == "interactive" && + errorRegex.exec(curFrame.document.baseURI)) { + sendError(new UnknownError("Error loading page"), command_id); return; } checkTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT); @@ -1675,9 +1674,8 @@ function switchToFrame(msg) { let wantedFrame; try { wantedFrame = elementManager.getKnownElement(msg.json.element, curFrame); //Frame Element - } - catch(e) { - sendError(e.message, e.code, e.stack, command_id); + } catch (e) { + sendError(e, command_id); } if (frames.length > 0) { @@ -1735,8 +1733,9 @@ function switchToFrame(msg) { } } } + if (foundFrame === null) { - sendError("Unable to locate frame: " + (msg.json.id || msg.json.element), 8, null, command_id); + sendError(new NoSuchFrameError("Unable to locate frame: " + (msg.json.id || msg.json.element)), command_id); return true; } @@ -1777,12 +1776,11 @@ function addCookie(msg) { if (!cookie.domain) { var location = curFrame.document.location; cookie.domain = location.hostname; - } - else { + } else { var currLocation = curFrame.location; var currDomain = currLocation.host; if (currDomain.indexOf(cookie.domain) == -1) { - sendError("You may only set cookies for the current domain", 24, null, msg.json.command_id); + sendError(new InvalidCookieDomainError("You may only set cookies for the current domain"), msg.json.command_id); } } @@ -1795,12 +1793,12 @@ function addCookie(msg) { var document = curFrame.document; if (!document || !document.contentType.match(/html/i)) { - sendError('You may only set cookies on html documents', 25, null, msg.json.command_id); + sendError(new UnableToSetCookie("You may only set cookies on html documents"), msg.json.command_id); } let added = sendSyncMessage("Marionette:addCookie", {value: cookie}); if (added[0] !== true) { - sendError("Error setting cookie", 13, null, msg.json.command_id); + sendError(new UnknownError("Error setting cookie"), msg.json.command_id); return; } sendOk(msg.json.command_id); @@ -1841,7 +1839,7 @@ function deleteCookie(msg) { if (cookie.name == toDelete) { let deleted = sendSyncMessage("Marionette:deleteCookie", {value: cookie}); if (deleted[0] !== true) { - sendError("Could not delete cookie: " + msg.json.name, 13, null, msg.json.command_id); + sendError(new UnknownError("Could not delete cookie: " + msg.json.name), msg.json.command_id); return; } } @@ -1858,7 +1856,7 @@ function deleteAllCookies(msg) { for (let cookie of cookies) { let deleted = sendSyncMessage("Marionette:deleteCookie", {value: cookie}); if (!deleted[0]) { - sendError("Could not delete cookie: " + JSON.stringify(cookie), 13, null, msg.json.command_id); + sendError(new UnknownError("Could not delete cookie: " + JSON.stringify(cookie)), msg.json.command_id); return; } } @@ -1912,9 +1910,8 @@ function emulatorCmdResult(msg) { } try { cb(message.result); - } - catch(e) { - sendError(e.message, e.code, e.stack, -1); + } catch (e) { + sendError(e, -1); return; } } diff --git a/testing/marionette/sendkeys.js b/testing/marionette/sendkeys.js index 096330afc0aa..eb2b8e050f1e 100644 --- a/testing/marionette/sendkeys.js +++ b/testing/marionette/sendkeys.js @@ -17,8 +17,11 @@ */ let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("chrome://marionette/content/error.js"); + let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"] - .getService(Ci.mozIJSSubScriptLoader); + .getService(Ci.mozIJSSubScriptLoader); let utils = {}; loader.loadSubScript("chrome://marionette/content/EventUtils.js", utils); @@ -138,8 +141,7 @@ function sendKeysToElement (document, element, keysToSend, successCallback, erro sendSingleKey(c, modifiers, document); } successCallback(command_id); - } - else { - errorCallback("Element is not visible", 11, null, command_id); + } else { + errorCallback(new ElementNotVisibleError("Element is not visible"), command_id); } }; diff --git a/testing/mochitest/mach_commands.py b/testing/mochitest/mach_commands.py index 4fc0033d4866..6d12e5650b69 100644 --- a/testing/mochitest/mach_commands.py +++ b/testing/mochitest/mach_commands.py @@ -844,7 +844,7 @@ class MachCommands(MachCommandBase): elif conditions.is_emulator(self): return self.run_mochitest_remote(test_paths, **kwargs) elif conditions.is_b2g_desktop(self): - return self.run_b2g_desktop(test_paths, **kwargs) + return self.run_mochitest_b2g_desktop(test_paths, **kwargs) elif conditions.is_android(self): return self.run_mochitest_android(test_paths, **kwargs) diff --git a/testing/talos/talos.json b/testing/talos/talos.json index ba2e48f0a4d3..40eb39efe7ae 100644 --- a/testing/talos/talos.json +++ b/testing/talos/talos.json @@ -1,11 +1,11 @@ { "talos.zip": { - "url": "http://talos-bundles.pvt.build.mozilla.org/zips/talos.16e23a6dde72.zip", + "url": "http://talos-bundles.pvt.build.mozilla.org/zips/talos.3dc0c42bd761.zip", "path": "" }, "global": { "talos_repo": "https://hg.mozilla.org/build/talos", - "talos_revision": "16e23a6dde72" + "talos_revision": "3dc0c42bd761" }, "extra_options": { "android": [ "--apkPath=%(apk_path)s" ] diff --git a/testing/xpcshell/example/unit/check_profile.js b/testing/xpcshell/example/unit/check_profile.js new file mode 100644 index 000000000000..17f506f6910b --- /dev/null +++ b/testing/xpcshell/example/unit/check_profile.js @@ -0,0 +1,52 @@ +/* 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/. */ + +const {classes: Cc, interfaces: Ci} = Components; + +function check_profile_dir(profd) +{ + Assert.ok(profd.exists()); + Assert.ok(profd.isDirectory()); + let dirSvc = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties); + let profd2 = dirSvc.get("ProfD", Ci.nsILocalFile); + Assert.ok(profd2.exists()); + Assert.ok(profd2.isDirectory()); + // make sure we got the same thing back... + Assert.ok(profd.equals(profd2)); +} + +function check_do_get_profile(fireProfileAfterChange) +{ + const observedTopics = new Map([ + ["profile-do-change", 0], + ["profile-after-change", 0], + ]); + const expectedTopics = new Map(observedTopics); + + const obs = Cc["@mozilla.org/observer-service;1"] + .getService(Ci.nsIObserverService); + for (let [topic,] of observedTopics) { + obs.addObserver(() => { + let val = observedTopics.get(topic) + 1; + observedTopics.set(topic, val); + }, topic, false); + } + + // Trigger profile creation. + let profd = do_get_profile(); + check_profile_dir(profd); + + // Check the observed topics + expectedTopics.set("profile-do-change", 1); + if (fireProfileAfterChange) { + expectedTopics.set("profile-after-change", 1); + } + Assert.deepEqual(observedTopics, expectedTopics); + + // A second do_get_profile() should not trigger more notifications. + profd = do_get_profile(); + check_profile_dir(profd); + Assert.deepEqual(observedTopics, expectedTopics); +} diff --git a/testing/xpcshell/example/unit/test_profile.js b/testing/xpcshell/example/unit/test_profile.js index 35b8055b248f..29a34c7c8cda 100644 --- a/testing/xpcshell/example/unit/test_profile.js +++ b/testing/xpcshell/example/unit/test_profile.js @@ -6,14 +6,6 @@ function run_test() { - let profd = do_get_profile(); - do_check_true(profd.exists()); - do_check_true(profd.isDirectory()); - let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] - .getService(Components.interfaces.nsIProperties); - let profd2 = dirSvc.get("ProfD", Components.interfaces.nsILocalFile); - do_check_true(profd2.exists()); - do_check_true(profd2.isDirectory()); - // make sure we got the same thing back... - do_check_true(profd.equals(profd2)); + load("check_profile.js"); + check_do_get_profile(false); } diff --git a/testing/xpcshell/example/unit/test_profile_afterChange.js b/testing/xpcshell/example/unit/test_profile_afterChange.js new file mode 100644 index 000000000000..d3c4ce031ff0 --- /dev/null +++ b/testing/xpcshell/example/unit/test_profile_afterChange.js @@ -0,0 +1,11 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* 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/. */ + +function run_test() +{ + load("check_profile.js"); + check_do_get_profile(true); +} diff --git a/testing/xpcshell/example/unit/xpcshell.ini b/testing/xpcshell/example/unit/xpcshell.ini index daca93a716e0..3af6770af343 100644 --- a/testing/xpcshell/example/unit/xpcshell.ini +++ b/testing/xpcshell/example/unit/xpcshell.ini @@ -13,6 +13,7 @@ support-files = import_sub_module.jsm load_subscript.js location_load.js + check_profile.js [test_check_nsIException.js] [test_check_nsIException_failing.js] @@ -27,6 +28,7 @@ fail-if = true [test_load_httpd_js.js] [test_location.js] [test_profile.js] +[test_profile_afterChange.js] [test_sample.js] [test_fail.js] diff --git a/testing/xpcshell/head.js b/testing/xpcshell/head.js index 44bebd745096..3fbf8c02351e 100644 --- a/testing/xpcshell/head.js +++ b/testing/xpcshell/head.js @@ -1108,9 +1108,10 @@ function do_get_minidumpdir() { * Registers a directory with the profile service, * and return the directory as an nsILocalFile. * + * @param notifyProfileAfterChange Whether to notify for "profile-after-change". * @return nsILocalFile of the profile directory. */ -function do_get_profile() { +function do_get_profile(notifyProfileAfterChange = false) { if (!runningInParent) { _testLogger.info("Ignoring profile creation from child process."); return null; @@ -1173,6 +1174,9 @@ function do_get_profile() { if (!_profileInitialized) { obsSvc.notifyObservers(null, "profile-do-change", "xpcshell-do-get-profile"); _profileInitialized = true; + if (notifyProfileAfterChange) { + obsSvc.notifyObservers(null, "profile-after-change", "xpcshell-do-get-profile"); + } } // The methods of 'provider' will retain this scope so null out everything diff --git a/toolkit/modules/AppConstants.jsm b/toolkit/modules/AppConstants.jsm index 0da1d924617f..399caf5618f9 100644 --- a/toolkit/modules/AppConstants.jsm +++ b/toolkit/modules/AppConstants.jsm @@ -151,6 +151,13 @@ this.AppConstants = Object.freeze({ false, #endif + DEBUG: +#ifdef DEBUG + true, +#else + false, +#endif + MOZ_APP_NAME: "@MOZ_APP_NAME@", MOZ_APP_VERSION: "@MOZ_APP_VERSION@", MOZ_BUILD_APP: "@MOZ_BUILD_APP@", diff --git a/toolkit/modules/ObjectUtils.jsm b/toolkit/modules/ObjectUtils.jsm index d97c2349a525..04b9a1ac217c 100644 --- a/toolkit/modules/ObjectUtils.jsm +++ b/toolkit/modules/ObjectUtils.jsm @@ -14,6 +14,12 @@ this.EXPORTED_SYMBOLS = [ const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components; +Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); + +// Used only to cause test failures. +XPCOMUtils.defineLazyModuleGetter(this, "Promise", + "resource://gre/modules/Promise.jsm"); + this.ObjectUtils = { /** * This tests objects & values for deep equality. @@ -30,6 +36,25 @@ this.ObjectUtils = { deepEqual: function(a, b) { return _deepEqual(a, b); }, + + /** + * A thin wrapper on an object, designed to prevent client code from + * accessing non-existent properties because of typos. + * + * // Without `strict` + * let foo = { myProperty: 1 }; + * foo.MyProperty; // undefined + * + * // With `strict` + * let strictFoo = ObjectUtils.strict(foo); + * strictFoo.myProperty; // 1 + * strictFoo.MyProperty; // TypeError: No such property "MyProperty" + * + * Note that `strict` has no effect in non-DEBUG mode. + */ + strict: function(obj) { + return _strict(obj); + } }; // ... Start of previously MIT-licensed code. @@ -129,3 +154,21 @@ function objEquiv(a, b) { } // ... End of previously MIT-licensed code. + +function _strict(obj) { + if (typeof obj != "object") { + throw new TypeError("Expected an object"); + } + + return new Proxy(obj, { + get: function(target, name) { + if (name in obj) { + return obj[name]; + } + + let error = new TypeError(`No such property: "${name}"`); + Promise.reject(error); // Cause an xpcshell/mochitest failure. + throw error; + } + }); +} diff --git a/toolkit/modules/tests/xpcshell/test_ObjectUtils_strict.js b/toolkit/modules/tests/xpcshell/test_ObjectUtils_strict.js new file mode 100644 index 000000000000..fb522b5f7a66 --- /dev/null +++ b/toolkit/modules/tests/xpcshell/test_ObjectUtils_strict.js @@ -0,0 +1,32 @@ +"use strict"; + +let {ObjectUtils} = Components.utils.import("resource://gre/modules/ObjectUtils.jsm", {}); +let {Promise} = Components.utils.import("resource://gre/modules/Promise.jsm", {}); + +add_task(function* init() { + // The code will cause uncaught rejections on purpose. + Promise.Debugging.clearUncaughtErrorObservers(); +}); + +add_task(function* test_strict() { + let loose = { a: 1 }; + let strict = ObjectUtils.strict(loose); + + loose.a; // Should not throw. + loose.b || undefined; // Should not throw. + + strict.a; // Should not throw. + Assert.throws(() => strict.b, /No such property: "b"/); + "b" in strict; // Should not throw. + strict.b = 2; + strict.b; // Should not throw. + + Assert.throws(() => strict.c, /No such property: "c"/); + "c" in strict; // Should not throw. + loose.c = 3; + strict.c; // Should not throw. +}); + +function run_test() { + run_next_test(); +} diff --git a/toolkit/modules/tests/xpcshell/xpcshell.ini b/toolkit/modules/tests/xpcshell/xpcshell.ini index a6ae02d341c2..9725d5ad6b0e 100644 --- a/toolkit/modules/tests/xpcshell/xpcshell.ini +++ b/toolkit/modules/tests/xpcshell/xpcshell.ini @@ -17,6 +17,7 @@ support-files = [test_Log.js] [test_NewTabUtils.js] [test_ObjectUtils.js] +[test_ObjectUtils_strict.js] [test_PermissionsUtils.js] [test_Preferences.js] [test_Promise.js] diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 6e4e03fd9dd3..83165208acc7 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -2728,21 +2728,6 @@ static void MakeOrSetMinidumpPath(nsIFile* profD) const nsXREAppData* gAppData = nullptr; #ifdef MOZ_WIDGET_GTK -#include "prlink.h" -typedef void (*_g_set_application_name_fn)(const gchar *application_name); -typedef void (*_gtk_window_set_auto_startup_notification_fn)(gboolean setting); - -static PRFuncPtr FindFunction(const char* aName) -{ - PRLibrary *lib = nullptr; - PRFuncPtr result = PR_FindFunctionSymbolAndLibrary(aName, &lib); - // Since the library was already loaded, we can safely unload it here. - if (lib) { - PR_UnloadLibrary(lib); - } - return result; -} - static void MOZ_gdk_display_close(GdkDisplay *display) { #if CLEANUP_MEMORY @@ -3656,17 +3641,8 @@ XREMain::XRE_mainStartup(bool* aExitFlag) } #endif #if defined(MOZ_WIDGET_GTK) - // g_set_application_name () is only defined in glib2.2 and higher. - _g_set_application_name_fn _g_set_application_name = - (_g_set_application_name_fn)FindFunction("g_set_application_name"); - if (_g_set_application_name) { - _g_set_application_name(mAppData->name); - } - _gtk_window_set_auto_startup_notification_fn _gtk_window_set_auto_startup_notification = - (_gtk_window_set_auto_startup_notification_fn)FindFunction("gtk_window_set_auto_startup_notification"); - if (_gtk_window_set_auto_startup_notification) { - _gtk_window_set_auto_startup_notification(false); - } + g_set_application_name(mAppData->name); + gtk_window_set_auto_startup_notification(false); #if (MOZ_WIDGET_GTK == 2) gtk_widget_set_default_colormap(gdk_rgb_get_colormap()); diff --git a/view/nsView.cpp b/view/nsView.cpp index 41703691011d..0777d2ce0bca 100644 --- a/view/nsView.cpp +++ b/view/nsView.cpp @@ -770,9 +770,9 @@ void nsView::List(FILE* out, int32_t aIndent) const nscoord p2a = mViewManager->AppUnitsPerDevPixel(); nsIntRect rect; mWindow->GetClientBounds(rect); - nsRect windowBounds = rect.ToAppUnits(p2a); + nsRect windowBounds = ToAppUnits(rect, p2a); mWindow->GetBounds(rect); - nsRect nonclientBounds = rect.ToAppUnits(p2a); + nsRect nonclientBounds = ToAppUnits(rect, p2a); nsrefcnt widgetRefCnt = mWindow.get()->AddRef() - 1; mWindow.get()->Release(); int32_t Z = mWindow->GetZIndex(); diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp index fce226fe627e..c5d5eacabc97 100644 --- a/view/nsViewManager.cpp +++ b/view/nsViewManager.cpp @@ -475,7 +475,7 @@ void nsViewManager::FlushDirtyRegionToWidget(nsView* aView) // If we draw the frame counter we need to make sure we invalidate the area // for it to make it on screen if (gfxPrefs::DrawFrameCounter()) { - nsRect counterBounds = gfxPlatform::FrameCounterBounds().ToAppUnits(AppUnitsPerDevPixel()); + nsRect counterBounds = ToAppUnits(gfxPlatform::FrameCounterBounds(), AppUnitsPerDevPixel()); r = r.Or(r, counterBounds); } @@ -570,9 +570,8 @@ nsViewManager::InvalidateWidgetArea(nsView *aWidgetView, nsTArray clipRects; childWidget->GetWindowClipRegion(&clipRects); for (uint32_t i = 0; i < clipRects.Length(); ++i) { - nsRect rr = (clipRects[i] + bounds.TopLeft()). - ToAppUnits(AppUnitsPerDevPixel()); - children.Or(children, rr - aWidgetView->ViewToWidgetOffset()); + nsRect rr = ToAppUnits(clipRects[i] + bounds.TopLeft(), AppUnitsPerDevPixel()); + children.Or(children, rr - aWidgetView->ViewToWidgetOffset()); children.SimplifyInward(20); } #endif diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index 69d7a25934d7..716d639b0d78 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -1115,7 +1115,7 @@ PuppetWidget::GetChromeDimensions() NS_WARNING("PuppetWidget without Tab does not have chrome information."); return nsIntPoint(); } - return GetOwningTabChild()->GetChromeDisplacement(); + return LayoutDeviceIntPoint::ToUntyped(GetOwningTabChild()->GetChromeDisplacement()); } nsIntPoint diff --git a/widget/android/AndroidDirectTexture.h b/widget/android/AndroidDirectTexture.h index bf7a603b98d2..8582b8582f5f 100644 --- a/widget/android/AndroidDirectTexture.h +++ b/widget/android/AndroidDirectTexture.h @@ -9,8 +9,7 @@ #include "gfxTypes.h" #include "mozilla/Mutex.h" #include "AndroidGraphicBuffer.h" - -struct nsIntRect; +#include "nsRect.h" namespace mozilla { diff --git a/widget/android/AndroidGraphicBuffer.h b/widget/android/AndroidGraphicBuffer.h index a7af87bf8464..269f8680a00d 100644 --- a/widget/android/AndroidGraphicBuffer.h +++ b/widget/android/AndroidGraphicBuffer.h @@ -7,12 +7,11 @@ #define AndroidGraphicBuffer_h_ #include "gfxTypes.h" +#include "nsRect.h" typedef void* EGLImageKHR; typedef void* EGLClientBuffer; -struct nsIntRect; - namespace mozilla { /** diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 169ec8095f19..ca7eb0669849 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -2655,7 +2655,7 @@ RectTextureImage::BeginUpdate(const nsIntSize& aNewSize, mUpdateRegion = aDirtyRegion; if (aNewSize != mUsedSize) { mUsedSize = aNewSize; - mUpdateRegion = nsIntRect(nsIntPoint(0, 0), aNewSize); + mUpdateRegion = gfx::IntRect(gfx::IntPoint(0, 0), aNewSize); } if (mUpdateRegion.IsEmpty()) { @@ -2698,7 +2698,7 @@ RectTextureImage::EndUpdate(bool aKeepSurface) } if (overwriteTexture || !CanUploadSubtextures()) { - updateRegion = nsIntRect(nsIntPoint(0, 0), mTextureSize); + updateRegion = gfx::IntRect(gfx::IntPoint(0, 0), mTextureSize); } RefPtr snapshot = mUpdateDrawTarget->Snapshot(); diff --git a/widget/gonk/HwcComposer2D.cpp b/widget/gonk/HwcComposer2D.cpp index 491bf4886745..58182d139d47 100644 --- a/widget/gonk/HwcComposer2D.cpp +++ b/widget/gonk/HwcComposer2D.cpp @@ -140,7 +140,7 @@ HwcComposer2D::HwcComposer2D() ANativeWindow *win = GetGonkDisplay()->GetNativeWindow(); win->query(win, NATIVE_WINDOW_WIDTH, &screenSize.width); win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height); - mScreenRect = nsIntRect(nsIntPoint(0, 0), screenSize); + mScreenRect = gfx::IntRect(gfx::IntPoint(0, 0), screenSize); #if ANDROID_VERSION >= 17 int supported = 0; diff --git a/widget/gonk/ProcessOrientation.cpp b/widget/gonk/ProcessOrientation.cpp index 88940c63ad55..3a281dca392d 100644 --- a/widget/gonk/ProcessOrientation.cpp +++ b/widget/gonk/ProcessOrientation.cpp @@ -18,6 +18,7 @@ #include "base/basictypes.h" #include "mozilla/Hal.h" +#include "mozilla/unused.h" #include "nsIScreen.h" #include "nsIScreenManager.h" #include "OrientationObserver.h" @@ -321,6 +322,13 @@ ProcessOrientation::OnSensorChanged(const SensorData& event, RemainingMS(now, mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS)); + + // Avoid unused-but-set compile warnings for these variables, when LOGD is + // a no-op, as it is by default: + unused << isAccelerating; + unused << isFlat; + unused << isSwinging; + // Tell the listener. if (mProposedRotation != oldProposedRotation && mProposedRotation >= 0) { LOGD diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index a858d37ce62b..52e2f23e1814 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -161,7 +161,7 @@ nsWindow::nsWindow() win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height)) { NS_RUNTIMEABORT("Failed to get native window size, aborting..."); } - gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize); + gScreenBounds = gfx::IntRect(gfx::IntPoint(0, 0), screenSize); char propValue[PROPERTY_VALUE_MAX]; property_get("ro.sf.hwrotation", propValue, "0"); diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp index 8d5001bd7339..a3595009cc22 100644 --- a/widget/gtk/nsNativeThemeGTK.cpp +++ b/widget/gtk/nsNativeThemeGTK.cpp @@ -7,6 +7,7 @@ #include "nsThemeConstants.h" #include "gtkdrawing.h" +#include "gfx2DGlue.h" #include "nsIObserverService.h" #include "nsIServiceManager.h" #include "nsIFrame.h" @@ -849,7 +850,7 @@ nsNativeThemeGTK::DrawWidgetBackground(nsRenderingContext* aContext, nsIntRect overflowRect(widgetRect); nsIntMargin extraSize; if (GetExtraSizeForWidget(aFrame, aWidgetType, &extraSize)) { - overflowRect.Inflate(extraSize); + overflowRect.Inflate(gfx::ToIntMargin(extraSize)); } // This is the rectangle that will actually be drawn, in gdk pixels diff --git a/widget/nsBaseDragService.cpp b/widget/nsBaseDragService.cpp index 53665f42f071..cbd023226d7e 100644 --- a/widget/nsBaseDragService.cpp +++ b/widget/nsBaseDragService.cpp @@ -516,7 +516,7 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode, if (rootFrame && *aPresContext) { nsIntRect dragRect; aRegion->GetBoundingBox(&dragRect.x, &dragRect.y, &dragRect.width, &dragRect.height); - dragRect = dragRect.ToAppUnits(nsPresContext::AppUnitsPerCSSPixel()). + dragRect = ToAppUnits(dragRect, nsPresContext::AppUnitsPerCSSPixel()). ToOutsidePixels((*aPresContext)->AppUnitsPerDevPixel()); nsIntRect screenRect = rootFrame->GetScreenRectExternal(); diff --git a/widget/nsIPluginWidget.h b/widget/nsIPluginWidget.h index 7f95a70b9825..3ddf79d39f2d 100644 --- a/widget/nsIPluginWidget.h +++ b/widget/nsIPluginWidget.h @@ -4,12 +4,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.h" +#include "nsPoint.h" #define NS_IPLUGINWIDGET_IID \ { 0xEB9207E0, 0xD8F1, 0x44B9, \ { 0xB7, 0x52, 0xAF, 0x8E, 0x9F, 0x8E, 0xBD, 0xF7 } } -struct nsIntPoint; class nsIPluginInstanceOwner; /** diff --git a/widget/nsIRollupListener.h b/widget/nsIRollupListener.h index efb8e331a417..83c2dd142671 100644 --- a/widget/nsIRollupListener.h +++ b/widget/nsIRollupListener.h @@ -8,10 +8,10 @@ #define __nsIRollupListener_h__ #include "nsTArray.h" +#include "nsPoint.h" class nsIContent; class nsIWidget; -struct nsIntPoint; class nsIRollupListener { public: diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index 3248932b91c7..4e040b76d00c 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -1499,7 +1499,7 @@ void find_first_visible_parent(QWindow* aItem, QWindow*& aVisibleItem) NS_IMETHODIMP nsWindow::GetScreenBounds(nsIntRect &aRect) { - aRect = nsIntRect(nsIntPoint(0, 0), mBounds.Size()); + aRect = gfx::IntRect(gfx::IntPoint(0, 0), mBounds.Size()); if (mIsTopLevel) { QPoint pos = mWidget->position(); aRect.MoveTo(pos.x(), pos.y()); diff --git a/widget/tests/chrome.ini b/widget/tests/chrome.ini index fe8cb722ae70..66b3671f1821 100644 --- a/widget/tests/chrome.ini +++ b/widget/tests/chrome.ini @@ -83,7 +83,7 @@ support-files = chrome_context_menus_win.xul [test_plugin_input_event.html] skip-if = toolkit != "windows" [test_mouse_scroll.xul] -skip-if = toolkit != "windows" +skip-if = true support-files = window_mouse_scroll_win.html # Privacy relevant diff --git a/widget/windows/WinMouseScrollHandler.h b/widget/windows/WinMouseScrollHandler.h index b7d8a179b961..dd8f1ca6b1aa 100644 --- a/widget/windows/WinMouseScrollHandler.h +++ b/widget/windows/WinMouseScrollHandler.h @@ -14,9 +14,9 @@ #include "mozilla/TimeStamp.h" #include "Units.h" #include +#include "nsPoint.h" class nsWindowBase; -struct nsIntPoint; namespace mozilla { namespace widget { diff --git a/widget/windows/WinUtils.h b/widget/windows/WinUtils.h index 6dc620740154..0a4ae9daa78f 100644 --- a/widget/windows/WinUtils.h +++ b/widget/windows/WinUtils.h @@ -22,6 +22,7 @@ #include "nsAutoPtr.h" #include "nsString.h" #include "nsRegion.h" +#include "nsRect.h" #include "nsIRunnable.h" #include "nsICryptoHash.h" @@ -75,7 +76,6 @@ public: class nsWindow; class nsWindowBase; struct KeyPair; -struct nsIntRect; namespace mozilla { namespace widget { diff --git a/widget/windows/nsIMM32Handler.h b/widget/windows/nsIMM32Handler.h index 20d1240caf10..5145636ed40d 100644 --- a/widget/windows/nsIMM32Handler.h +++ b/widget/windows/nsIMM32Handler.h @@ -13,9 +13,9 @@ #include "nsTArray.h" #include "nsIWidget.h" #include "mozilla/EventForwards.h" +#include "nsRect.h" class nsWindow; -struct nsIntRect; namespace mozilla { namespace widget { diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 3b5bc554d548..9f22a55a56f5 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -1297,6 +1297,11 @@ void nsWindow::SetThemeRegion() void nsWindow::ConfigureAPZCTreeManager() { + // We currently only enable APZ for E10s windows. + if (!mozilla::BrowserTabsRemoteAutostart() || !mRequireOffMainThreadCompositing) { + return; + } + nsBaseWidget::ConfigureAPZCTreeManager(); // When APZ is enabled, we can actually enable raw touch events because we diff --git a/widget/windows/winrt/MetroInput.cpp b/widget/windows/winrt/MetroInput.cpp index 194efb9585e8..0212eb06f4d2 100644 --- a/widget/windows/winrt/MetroInput.cpp +++ b/widget/windows/winrt/MetroInput.cpp @@ -20,6 +20,7 @@ #include "mozilla/Preferences.h" // for Preferences #include "WinUtils.h" #include "nsIPresShell.h" +#include "nsPoint.h" // System headers (alphabetical) #include // ABI::Window::UI::Core namespace diff --git a/widget/windows/winrt/MetroInput.h b/widget/windows/winrt/MetroInput.h index 9e00039b097b..56c8105feacb 100644 --- a/widget/windows/winrt/MetroInput.h +++ b/widget/windows/winrt/MetroInput.h @@ -23,7 +23,6 @@ // Moz forward declarations class MetroWidget; -struct nsIntPoint; namespace mozilla { namespace dom { diff --git a/widget/windows/winrt/MetroUtils.h b/widget/windows/winrt/MetroUtils.h index ec1b650dbd00..97740b7d20d5 100644 --- a/widget/windows/winrt/MetroUtils.h +++ b/widget/windows/winrt/MetroUtils.h @@ -10,6 +10,7 @@ #include "nsString.h" #include "nsPoint.h" #include "WinUtils.h" +#include "nsRect.h" #include "mozwrlbase.h" @@ -40,7 +41,6 @@ class nsIBrowserDOMWindow; class nsIDOMWindow; -struct nsIntRect; namespace mozilla { namespace widget { diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h index 8e7cbe57398a..c7f56614a8e9 100644 --- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -1837,7 +1837,7 @@ public: nsTArray() {} explicit nsTArray(size_type aCapacity) : base_type(aCapacity) {} explicit nsTArray(const nsTArray& aOther) : base_type(aOther) {} - explicit nsTArray(nsTArray&& aOther) : base_type(mozilla::Move(aOther)) {} + MOZ_IMPLICIT nsTArray(nsTArray&& aOther) : base_type(mozilla::Move(aOther)) {} template explicit nsTArray(const nsTArray_Impl& aOther) diff --git a/xpcom/glue/nsThreadUtils.cpp b/xpcom/glue/nsThreadUtils.cpp index 9346bd1b550a..7513405c2590 100644 --- a/xpcom/glue/nsThreadUtils.cpp +++ b/xpcom/glue/nsThreadUtils.cpp @@ -93,6 +93,67 @@ NS_NewThread(nsIThread** aResult, nsIRunnable* aEvent, uint32_t aStackSize) return NS_OK; } +#if defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR) + +namespace { +class IgnoreThreadStatusRunnable : public nsIRunnable +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIRUNNABLE + +private: + virtual ~IgnoreThreadStatusRunnable() = default; +}; + +NS_IMPL_ISUPPORTS(IgnoreThreadStatusRunnable, nsIRunnable) + +NS_IMETHODIMP IgnoreThreadStatusRunnable::Run(void) +{ +#ifdef MOZILLA_INTERNAL_API + nsThreadManager::get()->SetIgnoreThreadStatus(); + return NS_OK; +#endif + return NS_ERROR_NOT_IMPLEMENTED; +} + +} // Anonymous namespace. +#endif // defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR) + +NS_METHOD +NS_NewUnmonitoredThread(nsIThread** aResult, + nsIRunnable* aEvent, + uint32_t aStackSize) +{ +#if defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR) + // Hold a ref while dispatching the initial event to match NS_NewThread() + nsCOMPtr thread; + nsresult rv = NS_NewThread(getter_AddRefs(thread), nullptr, aStackSize); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + nsCOMPtr ignoreme = new IgnoreThreadStatusRunnable(); + rv = thread->Dispatch(ignoreme, NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (aEvent) { + rv = thread->Dispatch(aEvent, NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } + + *aResult = nullptr; + thread.swap(*aResult); + return rv; +#else + return NS_NewThread(aResult, aEvent, aStackSize); +#endif +} + NS_METHOD NS_GetCurrentThread(nsIThread** aResult) { diff --git a/xpcom/glue/nsThreadUtils.h b/xpcom/glue/nsThreadUtils.h index af52029e9c0e..142371eea9d1 100644 --- a/xpcom/glue/nsThreadUtils.h +++ b/xpcom/glue/nsThreadUtils.h @@ -61,6 +61,17 @@ NS_NewThread(nsIThread** aResult, nsIRunnable* aInitialEvent = nullptr, uint32_t aStackSize = nsIThreadManager::DEFAULT_STACK_SIZE); +/** + * Create a new thread that is ignored in thread status monitoring by default on + * platforms with Nuwa process enabled. On non-Nuwa platforms, this function is + * identical to NS_NewThread(). + */ +extern NS_METHOD +NS_NewUnmonitoredThread(nsIThread** aResult, + nsIRunnable* aInitialEvent = nullptr, + uint32_t aStackSize = + nsIThreadManager::DEFAULT_STACK_SIZE); + /** * Creates a named thread, otherwise the same as NS_NewThread */ diff --git a/xpcom/string/nsTSubstring.cpp b/xpcom/string/nsTSubstring.cpp index e871583b7944..a351666aef79 100644 --- a/xpcom/string/nsTSubstring.cpp +++ b/xpcom/string/nsTSubstring.cpp @@ -53,7 +53,8 @@ nsTSubstring_CharT::MutatePrep(size_type aCapacity, char_type** aOldData, // If |aCapacity > kMaxCapacity|, then our doubling algorithm may not be // able to allocate it. Just bail out in cases like that. We don't want // to be allocating 2GB+ strings anyway. - PR_STATIC_ASSERT((sizeof(nsStringBuffer) & 0x1) == 0); + static_assert((sizeof(nsStringBuffer) & 0x1) == 0, + "bad size for nsStringBuffer"); const size_type kMaxCapacity = (size_type(-1) / 2 - sizeof(nsStringBuffer)) / sizeof(char_type) - 2; if (aCapacity > kMaxCapacity) { diff --git a/xpcom/tests/TestTArray.cpp b/xpcom/tests/TestTArray.cpp index 7a114b9be0af..80d359a879c3 100644 --- a/xpcom/tests/TestTArray.cpp +++ b/xpcom/tests/TestTArray.cpp @@ -289,6 +289,16 @@ class Moveable { /* static */ uint32_t Countable::sCount = 0; /* static */ uint32_t Moveable::sCount = 0; +static nsTArray returns_by_value() { + nsTArray result; + return result; +} + +static bool test_return_by_value() { + nsTArray result = returns_by_value(); + return true; +} + static bool test_move_array() { nsTArray countableArray; uint32_t i; @@ -1171,6 +1181,7 @@ static const struct Test { DECL_TEST(test_char_array), DECL_TEST(test_uint32_array), DECL_TEST(test_object_array), + DECL_TEST(test_return_by_value), DECL_TEST(test_move_array), DECL_TEST(test_string_array), DECL_TEST(test_comptr_array), diff --git a/xpcom/threads/nsTimerImpl.cpp b/xpcom/threads/nsTimerImpl.cpp index 0d4b98ced033..c52dc341cce8 100644 --- a/xpcom/threads/nsTimerImpl.cpp +++ b/xpcom/threads/nsTimerImpl.cpp @@ -277,7 +277,7 @@ nsTimerImpl::Release(void) nsTimerImpl::nsTimerImpl() : mClosure(nullptr), - mCallbackType(CALLBACK_TYPE_UNKNOWN), + mCallbackType(CallbackType::Unknown), mFiring(false), mArmed(false), mCanceled(false), @@ -398,7 +398,7 @@ nsTimerImpl::InitWithFuncCallback(nsTimerCallbackFunc aFunc, } ReleaseCallback(); - mCallbackType = CALLBACK_TYPE_FUNC; + mCallbackType = CallbackType::Function; mCallback.c = aFunc; mClosure = aClosure; @@ -415,7 +415,7 @@ nsTimerImpl::InitWithCallback(nsITimerCallback* aCallback, } ReleaseCallback(); - mCallbackType = CALLBACK_TYPE_INTERFACE; + mCallbackType = CallbackType::Interface; mCallback.i = aCallback; NS_ADDREF(mCallback.i); @@ -430,7 +430,7 @@ nsTimerImpl::Init(nsIObserver* aObserver, uint32_t aDelay, uint32_t aType) } ReleaseCallback(); - mCallbackType = CALLBACK_TYPE_OBSERVER; + mCallbackType = CallbackType::Observer; mCallback.o = aObserver; NS_ADDREF(mCallback.o); @@ -454,7 +454,7 @@ nsTimerImpl::Cancel() NS_IMETHODIMP nsTimerImpl::SetDelay(uint32_t aDelay) { - if (mCallbackType == CALLBACK_TYPE_UNKNOWN && mType == TYPE_ONE_SHOT) { + if (mCallbackType == CallbackType::Unknown && mType == TYPE_ONE_SHOT) { // This may happen if someone tries to re-use a one-shot timer // by re-setting delay instead of reinitializing the timer. NS_ERROR("nsITimer->SetDelay() called when the " @@ -513,7 +513,7 @@ nsTimerImpl::GetClosure(void** aClosure) NS_IMETHODIMP nsTimerImpl::GetCallback(nsITimerCallback** aCallback) { - if (mCallbackType == CALLBACK_TYPE_INTERFACE) { + if (mCallbackType == CallbackType::Interface) { NS_IF_ADDREF(*aCallback = mCallback.i); } else if (mTimerCallbackWhileFiring) { NS_ADDREF(*aCallback = mTimerCallbackWhileFiring); @@ -536,7 +536,7 @@ nsTimerImpl::GetTarget(nsIEventTarget** aTarget) NS_IMETHODIMP nsTimerImpl::SetTarget(nsIEventTarget* aTarget) { - if (NS_WARN_IF(mCallbackType != CALLBACK_TYPE_UNKNOWN)) { + if (NS_WARN_IF(mCallbackType != CallbackType::Unknown)) { return NS_ERROR_ALREADY_INITIALIZED; } @@ -609,7 +609,7 @@ nsTimerImpl::Fire() timeout -= TimeDuration::FromMilliseconds(mDelay); } - if (mCallbackType == CALLBACK_TYPE_INTERFACE) { + if (mCallbackType == CallbackType::Interface) { mTimerCallbackWhileFiring = mCallback.i; } mFiring = true; @@ -617,22 +617,22 @@ nsTimerImpl::Fire() // Handle callbacks that re-init the timer, but avoid leaking. // See bug 330128. CallbackUnion callback = mCallback; - unsigned callbackType = mCallbackType; - if (callbackType == CALLBACK_TYPE_INTERFACE) { + CallbackType callbackType = mCallbackType; + if (callbackType == CallbackType::Interface) { NS_ADDREF(callback.i); - } else if (callbackType == CALLBACK_TYPE_OBSERVER) { + } else if (callbackType == CallbackType::Observer) { NS_ADDREF(callback.o); } ReleaseCallback(); switch (callbackType) { - case CALLBACK_TYPE_FUNC: + case CallbackType::Function: callback.c(this, mClosure); break; - case CALLBACK_TYPE_INTERFACE: + case CallbackType::Interface: callback.i->Notify(this); break; - case CALLBACK_TYPE_OBSERVER: + case CallbackType::Observer: callback.o->Observe(static_cast(this), NS_TIMER_CALLBACK_TOPIC, nullptr); @@ -643,15 +643,15 @@ nsTimerImpl::Fire() // If the callback didn't re-init the timer, and it's not a one-shot timer, // restore the callback state. - if (mCallbackType == CALLBACK_TYPE_UNKNOWN && + if (mCallbackType == CallbackType::Unknown && mType != TYPE_ONE_SHOT && !mCanceled) { mCallback = callback; mCallbackType = callbackType; } else { // The timer was a one-shot, or the callback was reinitialized. - if (callbackType == CALLBACK_TYPE_INTERFACE) { + if (callbackType == CallbackType::Interface) { NS_RELEASE(callback.i); - } else if (callbackType == CALLBACK_TYPE_OBSERVER) { + } else if (callbackType == CallbackType::Observer) { NS_RELEASE(callback.o); } } @@ -819,22 +819,3 @@ nsTimerImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { return aMallocSizeOf(this); } - -// NOT FOR PUBLIC CONSUMPTION! -nsresult -NS_NewTimer(nsITimer** aResult, nsTimerCallbackFunc aCallback, void* aClosure, - uint32_t aDelay, uint32_t aType) -{ - nsTimerImpl* timer = new nsTimerImpl(); - NS_ADDREF(timer); - - nsresult rv = timer->InitWithFuncCallback(aCallback, aClosure, - aDelay, aType); - if (NS_FAILED(rv)) { - NS_RELEASE(timer); - return rv; - } - - *aResult = timer; - return NS_OK; -} diff --git a/xpcom/threads/nsTimerImpl.h b/xpcom/threads/nsTimerImpl.h index 27ebf8ff36cc..73ae251e2314 100644 --- a/xpcom/threads/nsTimerImpl.h +++ b/xpcom/threads/nsTimerImpl.h @@ -36,14 +36,6 @@ extern PRLogModuleInfo* GetTimerLog(); {0x84, 0x27, 0xfb, 0xab, 0x44, 0xf2, 0x9b, 0xc8} \ } -enum -{ - CALLBACK_TYPE_UNKNOWN = 0, - CALLBACK_TYPE_INTERFACE = 1, - CALLBACK_TYPE_FUNC = 2, - CALLBACK_TYPE_OBSERVER = 3 -}; - class nsTimerImpl final : public nsITimer { public: @@ -81,6 +73,13 @@ public: virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override; private: + enum class CallbackType : uint8_t { + Unknown = 0, + Interface = 1, + Function = 2, + Observer = 3, + }; + ~nsTimerImpl(); nsresult InitCommon(uint32_t aType, uint32_t aDelay); @@ -89,21 +88,24 @@ private: // if we're the last owner of the callback object, make // sure that we don't recurse into ReleaseCallback in case // the callback's destructor calls Cancel() or similar. - uint8_t cbType = mCallbackType; - mCallbackType = CALLBACK_TYPE_UNKNOWN; + CallbackType cbType = mCallbackType; + mCallbackType = CallbackType::Unknown; - if (cbType == CALLBACK_TYPE_INTERFACE) { + if (cbType == CallbackType::Interface) { NS_RELEASE(mCallback.i); - } else if (cbType == CALLBACK_TYPE_OBSERVER) { + } else if (cbType == CallbackType::Observer) { NS_RELEASE(mCallback.o); } } bool IsRepeating() const { - PR_STATIC_ASSERT(TYPE_ONE_SHOT < TYPE_REPEATING_SLACK); - PR_STATIC_ASSERT(TYPE_REPEATING_SLACK < TYPE_REPEATING_PRECISE); - PR_STATIC_ASSERT(TYPE_REPEATING_PRECISE < TYPE_REPEATING_PRECISE_CAN_SKIP); + static_assert(TYPE_ONE_SHOT < TYPE_REPEATING_SLACK, + "invalid ordering of timer types!"); + static_assert(TYPE_REPEATING_SLACK < TYPE_REPEATING_PRECISE, + "invalid ordering of timer types!"); + static_assert(TYPE_REPEATING_PRECISE < TYPE_REPEATING_PRECISE_CAN_SKIP, + "invalid ordering of timer types!"); return mType >= TYPE_REPEATING_SLACK; } @@ -127,8 +129,8 @@ private: // timer is firing. nsCOMPtr mTimerCallbackWhileFiring; - // These members are set by Init (called from NS_NewTimer) and never reset. - uint8_t mCallbackType; + // These members are set by Init and never reset. + CallbackType mCallbackType; // These members are set by the initiating thread, when the timer's type is // changed and during the period where it fires on that thread. diff --git a/xpfe/appshell/nsAppShellService.cpp b/xpfe/appshell/nsAppShellService.cpp index 0b52f29f4262..9375a097425d 100644 --- a/xpfe/appshell/nsAppShellService.cpp +++ b/xpfe/appshell/nsAppShellService.cpp @@ -393,7 +393,7 @@ nsAppShellService::CreateWindowlessBrowser(bool aIsChrome, nsIWebNavigation **aR NS_ERROR("Couldn't create instance of PuppetWidget"); return NS_ERROR_FAILURE; } - widget->Create(nullptr, 0, nsIntRect(nsIntPoint(0, 0), nsIntSize(0, 0)), + widget->Create(nullptr, 0, gfx::IntRect(gfx::IntPoint(0, 0), gfx::IntSize(0, 0)), nullptr); nsCOMPtr window = do_QueryInterface(navigation); window->InitWindow(0, widget, 0, 0, 0, 0); diff --git a/xpfe/appshell/test/chrome.ini b/xpfe/appshell/test/chrome.ini index 7b8193fe82b3..34f412b42796 100644 --- a/xpfe/appshell/test/chrome.ini +++ b/xpfe/appshell/test/chrome.ini @@ -2,3 +2,4 @@ skip-if = buildapp == 'b2g' [test_hiddenPrivateWindow.xul] +skip-if = toolkit == "windows" diff --git a/xulrunner/examples/simple/Makefile.in b/xulrunner/examples/simple/Makefile.in deleted file mode 100644 index cc894585c96b..000000000000 --- a/xulrunner/examples/simple/Makefile.in +++ /dev/null @@ -1,15 +0,0 @@ -# vim:set ts=8 sw=8 sts=8 noet: -# 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/. - -ifneq (,$(filter windows,$(MOZ_WIDGET_TOOLKIT))) -ICONS = icons/simple.ico -endif - -include $(topsrcdir)/config/rules.mk - -ifneq (,$(ICONS)) -libs:: $(ICONS) - $(INSTALL) $^ $(FINAL_TARGET)/chrome/icons/default -endif diff --git a/xulrunner/examples/simple/moz.build b/xulrunner/examples/simple/moz.build index 974a0a25335b..2a46f05c0283 100644 --- a/xulrunner/examples/simple/moz.build +++ b/xulrunner/examples/simple/moz.build @@ -17,3 +17,6 @@ JS_PREFERENCE_FILES += [ DIST_FILES += [ 'application.ini', ] + +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': + FINAL_TARGET_FILES.chrome.icons.default += ['icons/simple.ico']