Merge beta to m-r. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 24 Mar 2015 20:22:27 -0400
changeset 252108 7ec23d08cf32
parent 252102 07c827be741f (current diff)
parent 252107 8fda35675a3f (diff)
child 252109 f2bd23e3be4f
child 252111 936c52fa8e88
push id701
push userryanvm@gmail.com
push date2015-03-25 00:23 +0000
treeherdermozilla-release@7ec23d08cf32 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone37.0
Merge beta to m-r. a=merge
--- a/dom/html/HTMLObjectElement.cpp
+++ b/dom/html/HTMLObjectElement.cpp
@@ -40,16 +40,19 @@ HTMLObjectElement::HTMLObjectElement(alr
   SetBarredFromConstraintValidation(true);
 
   // By default we're in the loading state
   AddStatesSilently(NS_EVENT_STATE_LOADING);
 }
 
 HTMLObjectElement::~HTMLObjectElement()
 {
+#ifdef XP_MACOSX
+  OnFocusBlurPlugin(this, false);
+#endif
   UnregisterActivityObserver();
   DestroyImageLoadingContent();
 }
 
 bool
 HTMLObjectElement::IsDoneAddingChildren()
 {
   return mIsDoneAddingChildren;
@@ -101,30 +104,60 @@ NS_IMPL_ELEMENT_CLONE(HTMLObjectElement)
 
 // nsIConstraintValidation
 NS_IMPL_NSICONSTRAINTVALIDATION(HTMLObjectElement)
 
 #ifdef XP_MACOSX
 
 static nsIWidget* GetWidget(Element* aElement)
 {
-  nsIWidget* retval = NULL;
-  nsIFrame* frame = aElement->GetPrimaryFrame();
-  if (frame) {
-    retval = frame->GetNearestWidget();
-  }
-  return retval;
+  return nsContentUtils::WidgetForDocument(aElement->OwnerDoc());
 }
 
-static void OnFocusBlurPlugin(Element* aElement, bool aFocus)
+Element* HTMLObjectElement::sLastFocused = nullptr; // Weak
+
+class PluginFocusSetter : public nsRunnable
 {
-  nsIWidget* widget = GetWidget(aElement);
-  if (widget) {
-    bool value = aFocus;
-    widget->SetPluginFocused(value);
+public:
+  PluginFocusSetter(nsIWidget* aWidget, Element* aElement)
+  : mWidget(aWidget), mElement(aElement)
+  {
+  }
+
+  NS_IMETHOD Run()
+  {
+    if (mElement) {
+      HTMLObjectElement::sLastFocused = mElement;
+      bool value = true;
+      mWidget->SetPluginFocused(value);
+    } else if (!HTMLObjectElement::sLastFocused) {
+      bool value = false;
+      mWidget->SetPluginFocused(value);
+    }
+
+    return NS_OK;
+  }
+
+private:
+  nsCOMPtr<nsIWidget> mWidget;
+  nsCOMPtr<Element> mElement;
+};
+
+void
+HTMLObjectElement::OnFocusBlurPlugin(Element* aElement, bool aFocus)
+{
+  if (aFocus || aElement == sLastFocused) {
+    if (!aFocus) {
+      sLastFocused = nullptr;
+    }
+    nsIWidget* widget = GetWidget(aElement);
+    if (widget) {
+      nsContentUtils::AddScriptRunner(
+        new PluginFocusSetter(widget, aFocus ? aElement : nullptr));
+    }
   }
 }
 
 void
 HTMLObjectElement::HandleFocusBlurPlugin(Element* aElement,
                                          WidgetEvent* aEvent)
 {
   if (!aEvent->mFlags.mIsTrusted) {
@@ -198,16 +231,24 @@ HTMLObjectElement::BindToTree(nsIDocumen
 
   return NS_OK;
 }
 
 void
 HTMLObjectElement::UnbindFromTree(bool aDeep,
                                   bool aNullParent)
 {
+#ifdef XP_MACOSX
+  // When a page is reloaded (when an nsIDocument's content is removed), the
+  // focused element isn't necessarily sent an NS_BLUR_CONTENT event. See
+  // nsFocusManager::ContentRemoved(). This means that a widget may think it
+  // still contains a focused plugin when it doesn't -- which in turn can
+  // disable text input in the browser window. See bug 1137229.
+  OnFocusBlurPlugin(this, false);
+#endif
   nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
   nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 
 
 nsresult
 HTMLObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
--- a/dom/html/HTMLObjectElement.h
+++ b/dom/html/HTMLObjectElement.h
@@ -28,17 +28,21 @@ public:
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
 #ifdef XP_MACOSX
   // nsIDOMEventTarget
   NS_IMETHOD PostHandleEvent(EventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
+  // Helper methods
+  static void OnFocusBlurPlugin(Element* aElement, bool aFocus);
   static void HandleFocusBlurPlugin(Element* aElement, WidgetEvent* aEvent);
+  // Weak pointer. Null if last action was blur.
+  static Element* sLastFocused;
 #endif
 
   // nsIDOMHTMLObjectElement
   NS_DECL_NSIDOMHTMLOBJECTELEMENT
 
   virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
--- a/dom/html/HTMLSharedObjectElement.cpp
+++ b/dom/html/HTMLSharedObjectElement.cpp
@@ -57,16 +57,19 @@ HTMLSharedObjectElement::SetItemValueTex
     nsGenericHTMLElement::SetItemValueText(aValue);
   } else {
     SetSrc(aValue);
   }
 }
 
 HTMLSharedObjectElement::~HTMLSharedObjectElement()
 {
+#ifdef XP_MACOSX
+  HTMLObjectElement::OnFocusBlurPlugin(this, false);
+#endif
   UnregisterActivityObserver();
   DestroyImageLoadingContent();
 }
 
 bool
 HTMLSharedObjectElement::IsDoneAddingChildren()
 {
   return mIsDoneAddingChildren;
@@ -154,16 +157,24 @@ HTMLSharedObjectElement::BindToTree(nsID
 
   return NS_OK;
 }
 
 void
 HTMLSharedObjectElement::UnbindFromTree(bool aDeep,
                                         bool aNullParent)
 {
+#ifdef XP_MACOSX
+  // When a page is reloaded (when an nsIDocument's content is removed), the
+  // focused element isn't necessarily sent an NS_BLUR_CONTENT event. See
+  // nsFocusManager::ContentRemoved(). This means that a widget may think it
+  // still contains a focused plugin when it doesn't -- which in turn can
+  // disable text input in the browser window. See bug 1137229.
+  HTMLObjectElement::OnFocusBlurPlugin(this, false);
+#endif
   nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 
 nsresult
 HTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
                                  nsIAtom *aPrefix, const nsAString &aValue,
--- a/dom/network/tests/test_udpsocket.html
+++ b/dom/network/tests/test_udpsocket.html
@@ -319,23 +319,23 @@ function testCloseBeforeOpened() {
   return socket.close().then(function() {
     ok(true, 'expected closedPromise to be resolved');
   }).then(socket.opened);
 }
 
 function testOpenWithoutClose() {
   info('test for open without close');
 
-  let opened = [];
+  let closed = [];
   for (let i = 0; i < 50; i++) {
     let socket = new UDPSocket();
-    opened.push(socket.opened);
+    closed.push(socket.closed);
   }
 
-  return Promise.all(opened);
+  return Promise.all(closed);
 }
 
 function testBFCache() {
   info('test for bfcache behavior');
 
   let socket = new UDPSocket();
 
   return socket.opened.then(function() {
@@ -384,16 +384,20 @@ function runTest() {
   .then(testOpenFailed)
   .then(testSendBeforeOpen)
   .then(testCloseBeforeOpened)
   .then(testOpenWithoutClose)
   .then(testBFCache)
   .then(function() {
     info('test finished');
     SimpleTest.finish();
+  })
+  .catch(function(err) {
+    ok(false, 'test failed due to: ' + err);
+    SimpleTest.finish();
   });
 }
 
 window.addEventListener('load', function () {
   SpecialPowers.pushPermissions([
     {type: 'udp-socket', allow: true, context: document}], function() {
     SpecialPowers.pushPrefEnv({
       'set': [
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -2221,16 +2221,17 @@ nsHTMLEditRules::WillDeleteSelection(Sel
       // Don't cross table boundaries
       if (leftNode && rightNode &&
           InDifferentTableElements(leftNode, rightNode)) {
         return NS_OK;
       }
 
       if (bDeletedBR) {
         // Put selection at edge of block and we are done.
+        NS_ENSURE_STATE(leafNode);
         ::DOMPoint newSel = GetGoodSelPointForNode(*leafNode, aAction);
         NS_ENSURE_STATE(newSel.node);
         aSelection->Collapse(newSel.node, newSel.offset);
         return NS_OK;
       }
 
       // Else we are joining content to block
 
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -174,19 +174,19 @@ TextureClientD3D11::TextureClientD3D11(I
   , mNeedsClear(false)
   , mNeedsClearWhite(false)
 {}
 
 TextureClientD3D11::~TextureClientD3D11()
 {
   if (mActor) {
     if (mTexture) {
-      KeepUntilFullDeallocation(MakeUnique<TKeepAlive<ID3D10Texture2D>>(mTexture10));
+      KeepUntilFullDeallocation(MakeUnique<TKeepAlive<ID3D11Texture2D>>(mTexture));
     } else if (mTexture10) {
-      KeepUntilFullDeallocation(MakeUnique<TKeepAlive<ID3D11Texture2D>>(mTexture));
+      KeepUntilFullDeallocation(MakeUnique<TKeepAlive<ID3D10Texture2D>>(mTexture10));
     }
   }
 #ifdef DEBUG
   // An Azure DrawTarget needs to be locked when it gets nullptr'ed as this is
   // when it calls EndDraw. This EndDraw should not execute anything so it
   // shouldn't -really- need the lock but the debug layer chokes on this.
   if (mDrawTarget) {
     MOZ_ASSERT(!mIsLocked);
--- a/widget/GfxDriverInfo.cpp
+++ b/widget/GfxDriverInfo.cpp
@@ -23,49 +23,53 @@ GfxDriverInfo::GfxDriverInfo()
     mAdapterVendor(GfxDriverInfo::GetDeviceVendor(VendorAll)),
     mDevices(allDevices),
     mDeleteDevices(false),
     mFeature(allFeatures),
     mFeatureStatus(nsIGfxInfo::FEATURE_STATUS_OK),
     mComparisonOp(DRIVER_COMPARISON_IGNORED),
     mDriverVersion(0),
     mDriverVersionMax(0),
-    mSuggestedVersion(nullptr)
+    mSuggestedVersion(nullptr),
+    mGpu2(false)
 {}
 
 GfxDriverInfo::GfxDriverInfo(OperatingSystem os, nsAString& vendor,
                              GfxDeviceFamily* devices,
                              int32_t feature, int32_t featureStatus,
                              VersionComparisonOp op,
                              uint64_t driverVersion,
                              const char *suggestedVersion /* = nullptr */,
-                             bool ownDevices /* = false */)
+                             bool ownDevices /* = false */,
+                             bool gpu2 /* = false */)
   : mOperatingSystem(os),
     mOperatingSystemVersion(0),
     mAdapterVendor(vendor),
     mDevices(devices),
     mDeleteDevices(ownDevices),
     mFeature(feature),
     mFeatureStatus(featureStatus),
     mComparisonOp(op),
     mDriverVersion(driverVersion),
     mDriverVersionMax(0),
-    mSuggestedVersion(suggestedVersion)
+    mSuggestedVersion(suggestedVersion),
+    mGpu2(gpu2)
 {}
 
 GfxDriverInfo::GfxDriverInfo(const GfxDriverInfo& aOrig)
   : mOperatingSystem(aOrig.mOperatingSystem),
     mOperatingSystemVersion(aOrig.mOperatingSystemVersion),
     mAdapterVendor(aOrig.mAdapterVendor),
     mFeature(aOrig.mFeature),
     mFeatureStatus(aOrig.mFeatureStatus),
     mComparisonOp(aOrig.mComparisonOp),
     mDriverVersion(aOrig.mDriverVersion),
     mDriverVersionMax(aOrig.mDriverVersionMax),
-    mSuggestedVersion(aOrig.mSuggestedVersion)
+    mSuggestedVersion(aOrig.mSuggestedVersion),
+    mGpu2(aOrig.mGpu2)
 {
   // If we're managing the lifetime of the device family, we have to make a
   // copy of the original's device family.
   if (aOrig.mDeleteDevices && aOrig.mDevices) {
     mDevices = new GfxDeviceFamily;
     *mDevices = *aOrig.mDevices;
   } else {
     mDevices = aOrig.mDevices;
@@ -209,16 +213,45 @@ const GfxDeviceFamily* GfxDriverInfo::Ge
       APPEND_DEVICE(0x7291);
       break;
     case Geforce7300GT:
       APPEND_DEVICE(0x0393);
       break;
     case Nvidia310M:
       APPEND_DEVICE(0x0A70);
       break;
+    case Bug1137716:
+      APPEND_DEVICE(0x0a29);
+      APPEND_DEVICE(0x0a2b);
+      APPEND_DEVICE(0x0a2d);
+      APPEND_DEVICE(0x0a35);
+      APPEND_DEVICE(0x0a6c);
+      APPEND_DEVICE(0x0a70);
+      APPEND_DEVICE(0x0a72);
+      APPEND_DEVICE(0x0a7a);
+      APPEND_DEVICE(0x0caf);
+      // GF180M ids
+      APPEND_DEVICE(0x0de3);
+      APPEND_DEVICE(0x0de8);
+      APPEND_DEVICE(0x0de9);
+      APPEND_DEVICE(0x0dea);
+      APPEND_DEVICE(0x0deb);
+      APPEND_DEVICE(0x0dec);
+      APPEND_DEVICE(0x0ded);
+      APPEND_DEVICE(0x0dee);
+      APPEND_DEVICE(0x0def);
+      APPEND_DEVICE(0x0df0);
+      APPEND_DEVICE(0x0df1);
+      APPEND_DEVICE(0x0df2);
+      APPEND_DEVICE(0x0df3);
+      APPEND_DEVICE(0x0df4);
+      APPEND_DEVICE(0x0df5);
+      APPEND_DEVICE(0x0df6);
+      APPEND_DEVICE(0x0df7);
+      break;
     case AMDRadeonHD5800:
       APPEND_DEVICE(0x6899);
       break;
     // This should never happen, but we get a warning if we don't handle this.
     case DeviceFamilyMax:
       NS_WARNING("Invalid DeviceFamily id");
       break;
   }
--- a/widget/GfxDriverInfo.h
+++ b/widget/GfxDriverInfo.h
@@ -20,16 +20,27 @@
       MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
                  driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
                  driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
       GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion); \
       info.mDriverVersionMax = driverVersionMax; \
       mDriverInfo->AppendElement(info); \
     } while (false)
 
+#define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, suggestedVersion) \
+    do { \
+      MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
+                 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
+                 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
+      GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion, false, true); \
+      info.mDriverVersionMax = driverVersionMax; \
+      mDriverInfo->AppendElement(info); \
+    } while (false)
+
+
 namespace mozilla {
 namespace widget {
 
 enum OperatingSystem {
   DRIVER_OS_UNKNOWN = 0,
   DRIVER_OS_WINDOWS_XP,
   DRIVER_OS_WINDOWS_SERVER_2003,
   DRIVER_OS_WINDOWS_VISTA,
@@ -70,16 +81,17 @@ enum DeviceFamily {
   IntelGMAX4500HD,
   IntelHD3000,
   IntelMobileHDGraphics,
   NvidiaBlockD3D9Layers,
   RadeonX1000,
   Geforce7300GT,
   Nvidia310M,
   AMDRadeonHD5800,
+  Bug1137716,
   DeviceFamilyMax
 };
 
 enum DeviceVendor {
   VendorAll,
   VendorIntel,
   VendorNVIDIA,
   VendorAMD,
@@ -93,17 +105,17 @@ typedef nsTArray<nsString> GfxDeviceFami
 
 struct GfxDriverInfo
 {
   // If |ownDevices| is true, you are transferring ownership of the devices
   // array, and it will be deleted when this GfxDriverInfo is destroyed.
   GfxDriverInfo(OperatingSystem os, nsAString& vendor, GfxDeviceFamily* devices,
                 int32_t feature, int32_t featureStatus, VersionComparisonOp op,
                 uint64_t driverVersion, const char *suggestedVersion = nullptr,
-                bool ownDevices = false);
+                bool ownDevices = false, bool gpu2 = false);
 
   GfxDriverInfo();
   GfxDriverInfo(const GfxDriverInfo&);
   ~GfxDriverInfo();
 
   OperatingSystem mOperatingSystem;
   uint32_t mOperatingSystemVersion;
 
@@ -134,16 +146,18 @@ struct GfxDriverInfo
 
   static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
   static GfxDeviceFamily* mDeviceFamilies[DeviceFamilyMax];
 
   static const nsAString& GetDeviceVendor(DeviceVendor id);
   static nsAString* mDeviceVendors[DeviceVendorMax];
 
   nsString mModel, mHardware, mProduct, mManufacturer;
+
+  bool mGpu2;
 };
 
 #define GFX_DRIVER_VERSION(a,b,c,d) \
   ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d))
 
 inline uint64_t
 V(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
 {
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -599,33 +599,44 @@ GfxInfoBase::GetFeatureStatus(int32_t aF
 int32_t
 GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
                                          nsAString& aSuggestedVersion,
                                          int32_t aFeature,
                                          OperatingSystem os)
 {
   int32_t status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
 
-  nsAutoString adapterVendorID;
-  nsAutoString adapterDeviceID;
-  nsAutoString adapterDriverVersionString;
-  if (NS_FAILED(GetAdapterVendorID(adapterVendorID)) ||
-      NS_FAILED(GetAdapterDeviceID(adapterDeviceID)) ||
-      NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString)))
-  {
-    return 0;
-  }
+  uint32_t i = 0;
+  for (; i < info.Length(); i++) {
+    // XXX: it would be better not to do this everytime round the loop
+    nsAutoString adapterVendorID;
+    nsAutoString adapterDeviceID;
+    nsAutoString adapterDriverVersionString;
+    if (info[i].mGpu2) {
+      if (NS_FAILED(GetAdapterVendorID2(adapterVendorID)) ||
+          NS_FAILED(GetAdapterDeviceID2(adapterDeviceID)) ||
+          NS_FAILED(GetAdapterDriverVersion2(adapterDriverVersionString)))
+      {
+        return 0;
+      }
+    } else {
+      if (NS_FAILED(GetAdapterVendorID(adapterVendorID)) ||
+          NS_FAILED(GetAdapterDeviceID(adapterDeviceID)) ||
+          NS_FAILED(GetAdapterDriverVersion(adapterDriverVersionString)))
+      {
+        return 0;
+      }
+    }
 
 #if defined(XP_WIN) || defined(ANDROID)
-  uint64_t driverVersion;
-  ParseDriverVersion(adapterDriverVersionString, &driverVersion);
+    uint64_t driverVersion;
+    ParseDriverVersion(adapterDriverVersionString, &driverVersion);
 #endif
 
-  uint32_t i = 0;
-  for (; i < info.Length(); i++) {
+
     if (info[i].mOperatingSystem != DRIVER_OS_ALL &&
         info[i].mOperatingSystem != os)
     {
       continue;
     }
 
     if (info[i].mOperatingSystemVersion && info[i].mOperatingSystemVersion != OperatingSystemVersion()) {
         continue;
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -1077,16 +1077,24 @@ GfxInfo::GetGfxDriverInfo()
       nsIGfxInfo::FEATURE_DXVA, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
       DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions);
 
     /* Bug 1139503: DXVA crashes with ATI cards on windows 10. */
     APPEND_TO_DRIVER_BLOCKLIST2(DRIVER_OS_WINDOWS_10,
       (nsAString&)GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
       nsIGfxInfo::FEATURE_DXVA, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
       DRIVER_EQUAL, V(15,200,1006,0));
+
+    /* Bug 1137716: XXX this should really check for the matching Intel piece as well.
+     * Unfortunately, we don't have the infrastructure to do that */
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2(DRIVER_OS_WINDOWS_7,
+        (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(Bug1137716),
+      GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
+      DRIVER_BETWEEN_INCLUSIVE, V(8,7,12,5730), V(8,17,12,6901), "Nvidia driver > 8.17.12.6901");
+
   }
   return *mDriverInfo;
 }
 
 nsresult
 GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
                               int32_t *aStatus, 
                               nsAString & aSuggestedDriverVersion,