diff --git a/DEPS b/DEPS
index 3365dfd1..67e7306 100644
--- a/DEPS
+++ b/DEPS
@@ -43,7 +43,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '75076c2a96bc67b1c44cc283f85bac40ef456de3',
+  'v8_revision': '6b270a44e31ea4b473d6806039ee71b262ead725',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 57cccab..98aff681 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -725,7 +725,10 @@
 
 void BrowserAccessibility::Destroy() {
   // Allow the object to fire a TextRemoved notification.
-  manager_->NotifyAccessibilityEvent(ui::AX_EVENT_HIDE, this);
+  manager()->NotifyAccessibilityEvent(
+      BrowserAccessibilityEvent::FromTreeChange,
+      ui::AX_EVENT_HIDE,
+      this);
   node_ = NULL;
   manager_ = NULL;
 
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index 55982e9c..dd96eaa9b 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -65,7 +65,10 @@
 }
 
 void BrowserAccessibilityAndroid::OnLocationChanged() {
-  manager()->NotifyAccessibilityEvent(ui::AX_EVENT_LOCATION_CHANGED, this);
+  manager()->NotifyAccessibilityEvent(
+      BrowserAccessibilityEvent::FromTreeChange,
+      ui::AX_EVENT_LOCATION_CHANGED,
+      this);
 }
 
 base::string16 BrowserAccessibilityAndroid::GetValue() const {
@@ -1373,8 +1376,12 @@
     }
   }
 
-  if (GetRole() == ui::AX_ROLE_ALERT && first_time_)
-    manager()->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, this);
+  if (GetRole() == ui::AX_ROLE_ALERT && first_time_) {
+    manager()->NotifyAccessibilityEvent(
+        BrowserAccessibilityEvent::FromTreeChange,
+        ui::AX_EVENT_ALERT,
+        this);
+  }
 
   base::string16 live;
   if (GetString16Attribute(
@@ -1394,8 +1401,10 @@
   base::string16 text = GetText();
   if (cached_text_ != text) {
     if (!text.empty()) {
-      manager()->NotifyAccessibilityEvent(ui::AX_EVENT_SHOW,
-                                         this);
+      manager()->NotifyAccessibilityEvent(
+          BrowserAccessibilityEvent::FromTreeChange,
+          ui::AX_EVENT_SHOW,
+          this);
     }
     cached_text_ = text;
   }
diff --git a/content/browser/accessibility/browser_accessibility_event.cc b/content/browser/accessibility/browser_accessibility_event.cc
new file mode 100644
index 0000000..778c25a
--- /dev/null
+++ b/content/browser/accessibility/browser_accessibility_event.cc
@@ -0,0 +1,146 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/accessibility/browser_accessibility_event.h"
+
+#include <string>
+
+#include "base/strings/string_util.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+
+namespace content {
+
+namespace {
+std::string ReplaceNewlines(std::string str) {
+  std::string result;
+  base::ReplaceChars(str, "\n", "\\n", &result);
+  return result;
+}
+}  // namespace
+
+// static
+bool BrowserAccessibilityEvent::FailedToSend(Result result) {
+  switch (result) {
+    case Sent:
+    case NotNeededOnThisPlatform:
+    case DiscardedBecauseUserNavigatingAway:
+    case DiscardedBecauseLiveRegionBusy:
+      return false;
+    case FailedBecauseNoWindow:
+    case FailedBecauseNoFocus:
+    case FailedBecauseFrameIsDetached:
+      return true;
+  }
+
+  NOTREACHED();
+  return true;
+}
+
+#if !defined(OS_WIN)
+// static
+BrowserAccessibilityEvent* BrowserAccessibilityEvent::Create(
+    Source source,
+    ui::AXEvent event_type,
+    const BrowserAccessibility* target) {
+  return new BrowserAccessibilityEvent(source, event_type, target);
+}
+#endif  // !defined(OS_WIN)
+
+BrowserAccessibilityEvent::BrowserAccessibilityEvent(
+    Source source,
+    ui::AXEvent event_type,
+    const BrowserAccessibility* target)
+    : source_(source),
+      event_type_(event_type),
+      target_(target),
+      original_target_(target) {
+  DCHECK(target_);
+}
+
+BrowserAccessibilityEvent::~BrowserAccessibilityEvent() {
+}
+
+BrowserAccessibilityEvent::Result BrowserAccessibilityEvent::Fire() {
+  delete this;
+  return NotNeededOnThisPlatform;
+}
+
+std::string BrowserAccessibilityEvent::GetEventNameStr() {
+  return ui::ToString(event_type_);
+}
+
+void BrowserAccessibilityEvent::VerboseLog(Result result) {
+  std::string event_name = GetEventNameStr();
+
+  const char* result_str = nullptr;
+  switch (result) {
+    case Sent:
+      result_str = "Sent";
+      break;
+    case NotNeededOnThisPlatform:
+      result_str = "NotNeededOnThisPlatform";
+      break;
+    case DiscardedBecauseUserNavigatingAway:
+      result_str = "DiscardedBecauseUserNavigatingAway";
+      break;
+    case DiscardedBecauseLiveRegionBusy:
+      result_str = "DiscardedBecauseLiveRegionBusy";
+      break;
+    case FailedBecauseNoWindow:
+      result_str = "FailedBecauseNoWindow";
+      break;
+    case FailedBecauseNoFocus:
+      result_str = "FailedBecauseNoFocus";
+      break;
+    case FailedBecauseFrameIsDetached:
+      result_str = "FailedBecauseFrameIsDetached";
+      break;
+  }
+
+  const char* success_str = (result == Sent ? "+" : "-");
+
+  const char* source_str = nullptr;
+  switch (source_) {
+    case FromBlink:
+      source_str = "FromBlink";
+      break;
+    case FromChildFrameLoading:
+      source_str = "FromChildFrameLoading";
+      break;
+    case FromFindInPageResult:
+      source_str = "FromFindInPageResult";
+      break;
+    case FromRenderFrameHost:
+      source_str = "FromRenderFrameHost";
+      break;
+    case FromScroll:
+      source_str = "FromScroll";
+      break;
+    case FromTreeChange:
+      source_str = "FromTreeChange";
+      break;
+    case FromWindowFocusChange:
+      source_str = "FromWindowFocusChange";
+      break;
+  }
+
+  std::string original_target_str;
+  if (original_target_ != target_) {
+    original_target_str = " originalTarget=[["
+        + ReplaceNewlines(original_target_->GetData().ToString()) + "]]";
+  }
+
+  VLOG(1) << "Accessibility event"
+          << " " << success_str
+          << " " << event_name
+          << " result=" << result_str
+          << " source=" << source_str
+          << " unique_id=" << target_->unique_id()
+          << " target=[["
+          << ReplaceNewlines(target_->GetData().ToString()) << "]]"
+          << original_target_str;
+}
+
+}  // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_event.h b/content/browser/accessibility/browser_accessibility_event.h
new file mode 100644
index 0000000..470d8b2f
--- /dev/null
+++ b/content/browser/accessibility/browser_accessibility_event.h
@@ -0,0 +1,84 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_H_
+
+#include <string>
+
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/common/content_export.h"
+#include "ui/accessibility/ax_enums.h"
+
+namespace content {
+
+class BrowserAccessibility;
+
+class CONTENT_EXPORT BrowserAccessibilityEvent {
+ public:
+  enum Source {
+    FromBlink,
+    FromChildFrameLoading,
+    FromFindInPageResult,
+    FromRenderFrameHost,
+    FromScroll,
+    FromTreeChange,
+    FromWindowFocusChange,
+  };
+
+  enum Result {
+    Sent,
+    NotNeededOnThisPlatform,
+    DiscardedBecauseUserNavigatingAway,
+    DiscardedBecauseLiveRegionBusy,
+    FailedBecauseNoWindow,
+    FailedBecauseNoFocus,
+    FailedBecauseFrameIsDetached,
+  };
+
+  // Returns true if the given result indicates that sending the event failed.
+  // Returns false if the event was sent, or if it was not needed (which is
+  // not considered failure).
+  static bool FailedToSend(Result result);
+
+  static BrowserAccessibilityEvent* Create(Source source,
+                                           ui::AXEvent event_type,
+                                           const BrowserAccessibility* target);
+
+  // Construct a new accessibility event that should be sent via a
+  // platform-specific notification.
+  BrowserAccessibilityEvent(Source source,
+                            ui::AXEvent event_type,
+                            const BrowserAccessibility* target);
+  virtual ~BrowserAccessibilityEvent();
+
+  // Synchronously try to send the native accessibility event notification
+  // and return a result indicating the outcome. This deletes the event.
+  virtual Result Fire();
+
+  Source source() { return source_; }
+  ui::AXEvent event_type() { return event_type_; }
+  const BrowserAccessibility* target() { return target_; }
+  void set_target(const BrowserAccessibility* target) { target_ = target; }
+  void set_original_target(BrowserAccessibility* target) {
+    original_target_ = target;
+  }
+
+ protected:
+  virtual std::string GetEventNameStr();
+  void VerboseLog(Result result);
+
+ private:
+  Source source_;
+  ui::AXEvent event_type_;
+  const BrowserAccessibility* target_;
+  const BrowserAccessibility* original_target_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityEvent);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_H_
diff --git a/content/browser/accessibility/browser_accessibility_event_win.cc b/content/browser/accessibility/browser_accessibility_event_win.cc
new file mode 100644
index 0000000..effc4151
--- /dev/null
+++ b/content/browser/accessibility/browser_accessibility_event_win.cc
@@ -0,0 +1,100 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/accessibility/browser_accessibility_event_win.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/browser/accessibility/browser_accessibility_manager_win.h"
+
+namespace content {
+
+// static
+BrowserAccessibilityEvent* BrowserAccessibilityEvent::Create(
+    Source source,
+    ui::AXEvent event_type,
+    const BrowserAccessibility* target) {
+  LONG win_event_type = EVENT_MIN;
+  switch (event_type) {
+    case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
+      win_event_type = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
+      break;
+    case ui::AX_EVENT_ALERT:
+      win_event_type = EVENT_SYSTEM_ALERT;
+      break;
+    case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
+      win_event_type = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED;
+      break;
+    case ui::AX_EVENT_CHILDREN_CHANGED:
+      win_event_type = EVENT_OBJECT_REORDER;
+      break;
+    case ui::AX_EVENT_FOCUS:
+      win_event_type = EVENT_OBJECT_FOCUS;
+      break;
+    case ui::AX_EVENT_LIVE_REGION_CHANGED:
+      win_event_type = EVENT_OBJECT_LIVEREGIONCHANGED;
+      break;
+    case ui::AX_EVENT_LOAD_COMPLETE:
+      win_event_type = IA2_EVENT_DOCUMENT_LOAD_COMPLETE;
+      break;
+    case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
+      win_event_type = EVENT_SYSTEM_SCROLLINGEND;
+      break;
+    case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
+      win_event_type = EVENT_SYSTEM_SCROLLINGSTART;
+      break;
+    case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
+      win_event_type = EVENT_OBJECT_SELECTIONWITHIN;
+      break;
+    default:
+      break;
+  }
+
+  return new BrowserAccessibilityEventWin(
+      source,
+      event_type,
+      win_event_type,
+      target);
+}
+
+BrowserAccessibilityEventWin::BrowserAccessibilityEventWin(
+    Source source,
+    ui::AXEvent event_type,
+    LONG win_event_type,
+    const BrowserAccessibility* target)
+    : BrowserAccessibilityEvent(source, event_type, target),
+      win_event_type_(win_event_type) {
+}
+
+BrowserAccessibilityEventWin::~BrowserAccessibilityEventWin() {
+}
+
+BrowserAccessibilityEvent::Result BrowserAccessibilityEventWin::Fire() {
+  DCHECK(target()->manager());
+
+  if (win_event_type_ == EVENT_MIN) {
+    delete this;
+    return NotNeededOnThisPlatform;
+  }
+
+  Result result = target()->manager()->ToBrowserAccessibilityManagerWin()
+      ->FireWinAccessibilityEvent(this);
+
+  if (VLOG_IS_ON(1))
+    VerboseLog(result);
+
+  delete this;
+  return result;
+}
+
+std::string BrowserAccessibilityEventWin::GetEventNameStr() {
+  std::string result = base::UTF16ToUTF8(AccessibilityEventToString(
+      win_event_type_));
+  if (event_type() != ui::AX_EVENT_NONE)
+    result += "/" + ui::ToString(event_type());
+  return result;
+}
+
+}  // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_event_win.h b/content/browser/accessibility/browser_accessibility_event_win.h
new file mode 100644
index 0000000..1d1ac4e
--- /dev/null
+++ b/content/browser/accessibility/browser_accessibility_event_win.h
@@ -0,0 +1,38 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_WIN_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_WIN_H_
+
+#include <oleacc.h>
+
+#include "content/browser/accessibility/browser_accessibility_event.h"
+
+namespace content {
+
+class CONTENT_EXPORT BrowserAccessibilityEventWin
+    : public BrowserAccessibilityEvent {
+ public:
+  BrowserAccessibilityEventWin(Source source,
+                               ui::AXEvent event_type,
+                               LONG win_event_type,
+                               const BrowserAccessibility* target);
+  ~BrowserAccessibilityEventWin() override;
+
+  LONG win_event_type() { return win_event_type_; }
+
+  Result Fire() override;
+
+ protected:
+  std::string GetEventNameStr() override;
+
+  LONG win_event_type_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityEventWin);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_WIN_H_
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index df9c931..84c2ec0e 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -183,7 +183,15 @@
   return update;
 }
 
-void BrowserAccessibilityManager::FireFocusEventsIfNeeded() {
+void BrowserAccessibilityManager::NotifyAccessibilityEvent(
+    BrowserAccessibilityEvent::Source source,
+    ui::AXEvent event_type,
+    BrowserAccessibility* node) {
+  BrowserAccessibilityEvent::Create(source, event_type, node)->Fire();
+}
+
+void BrowserAccessibilityManager::FireFocusEventsIfNeeded(
+    BrowserAccessibilityEvent::Source source) {
   BrowserAccessibility* focus = GetFocus();
 
   // Don't fire focus events if the window itself doesn't have focus.
@@ -209,7 +217,7 @@
   }
 
   if (focus && focus != last_focused_node_)
-    FireFocusEvent(focus);
+    FireFocusEvent(source, focus);
 
   last_focused_node_ = focus;
   last_focused_manager_ = focus ? focus->manager() : nullptr;
@@ -219,8 +227,10 @@
   return true;
 }
 
-void BrowserAccessibilityManager::FireFocusEvent(BrowserAccessibility* node) {
-  NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, node);
+void BrowserAccessibilityManager::FireFocusEvent(
+    BrowserAccessibilityEvent::Source source,
+    BrowserAccessibility* node) {
+  NotifyAccessibilityEvent(source, ui::AX_EVENT_FOCUS, node);
 
   if (!g_focus_change_callback_for_testing.Get().is_null())
     g_focus_change_callback_for_testing.Get().Run();
@@ -292,7 +302,7 @@
 
 void BrowserAccessibilityManager::OnWindowFocused() {
   if (this == GetRootManager())
-    FireFocusEventsIfNeeded();
+    FireFocusEventsIfNeeded(BrowserAccessibilityEvent::FromWindowFocusChange);
 }
 
 void BrowserAccessibilityManager::OnWindowBlurred() {
@@ -318,15 +328,6 @@
   user_is_navigating_away_ = false;
 }
 
-void BrowserAccessibilityManager::GotMouseDown() {
-  BrowserAccessibility* focus = GetFocus();
-  if (!focus)
-    return;
-
-  osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
-  NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, focus);
-}
-
 bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() {
   return true;
 }
@@ -354,8 +355,10 @@
     if (!connected_to_parent_tree_node_) {
       parent->OnDataChanged();
       parent->UpdatePlatformAttributes();
-      parent->manager()->NotifyAccessibilityEvent(
-          ui::AX_EVENT_CHILDREN_CHANGED, parent);
+      NotifyAccessibilityEvent(
+          BrowserAccessibilityEvent::FromChildFrameLoading,
+          ui::AX_EVENT_CHILDREN_CHANGED,
+          parent);
       connected_to_parent_tree_node_ = true;
     }
   } else {
@@ -366,7 +369,8 @@
   // Screen readers might not do the right thing if they're not aware of what
   // has focus, so always try that first. Nothing will be fired if the window
   // itself isn't focused or if focus hasn't changed.
-  GetRootManager()->FireFocusEventsIfNeeded();
+  GetRootManager()->FireFocusEventsIfNeeded(
+      BrowserAccessibilityEvent::FromBlink);
 
   // Now iterate over the events again and fire the events other than focus
   // events.
@@ -398,7 +402,13 @@
     }
 
     // Fire the native event.
-    NotifyAccessibilityEvent(event_type, GetFromAXNode(node));
+    BrowserAccessibility* event_target = GetFromAXNode(node);
+    if (event_target) {
+      NotifyAccessibilityEvent(
+          BrowserAccessibilityEvent::FromBlink,
+          event_type,
+          event_target);
+    }
   }
 }
 
@@ -473,7 +483,10 @@
 
   // The "scrolled to anchor" notification is a great way to get a
   // screen reader to jump directly to a specific location in a document.
-  NotifyAccessibilityEvent(ui::AX_EVENT_SCROLLED_TO_ANCHOR, node);
+  NotifyAccessibilityEvent(
+      BrowserAccessibilityEvent::FromFindInPageResult,
+      ui::AX_EVENT_SCROLLED_TO_ANCHOR,
+      node);
 }
 
 BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus(
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index ad073bf..d875e8ae 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -15,6 +15,7 @@
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "content/browser/accessibility/ax_tree_id_registry.h"
+#include "content/browser/accessibility/browser_accessibility_event.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/ax_event_notification_details.h"
 #include "third_party/WebKit/public/web/WebAXEnums.h"
@@ -142,19 +143,22 @@
   static ui::AXTreeUpdate GetEmptyDocument();
 
   virtual void NotifyAccessibilityEvent(
-      ui::AXEvent event_type, BrowserAccessibility* node) { }
+      BrowserAccessibilityEvent::Source source,
+      ui::AXEvent event_type,
+      BrowserAccessibility* node);
 
   // Checks whether focus has changed since the last time it was checked,
   // taking into account whether the window has focus and which frame within
   // the frame tree has focus. If focus has changed, calls FireFocusEvent.
-  void FireFocusEventsIfNeeded();
+  void FireFocusEventsIfNeeded(BrowserAccessibilityEvent::Source source);
 
   // Return whether or not we are currently able to fire events.
   virtual bool CanFireEvents();
 
   // Fire a focus event. Virtual so that some platforms can customize it,
   // like firing a focus event on the root first, on Windows.
-  virtual void FireFocusEvent(BrowserAccessibility* node);
+  virtual void FireFocusEvent(BrowserAccessibilityEvent::Source source,
+                              BrowserAccessibility* node);
 
   // Return a pointer to the root of the tree, does not make a new reference.
   BrowserAccessibility* GetRoot();
@@ -186,10 +190,6 @@
   void NavigationSucceeded();
   void NavigationFailed();
 
-  // Called to notify the accessibility manager that a mouse down event
-  // occurred in the tab.
-  void GotMouseDown();
-
   // Send a message to the renderer to set focus to this node.
   void SetFocus(const BrowserAccessibility& node);
 
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index 1522967..0575e94d 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -193,6 +193,7 @@
 }
 
 void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
+    BrowserAccessibilityEvent::Source source,
     ui::AXEvent event_type,
     BrowserAccessibility* node) {
   JNIEnv* env = AttachCurrentThread();
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h
index 981af00..90d0064f 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.h
+++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -77,8 +77,10 @@
   bool ShouldExposePasswordText();
 
   // BrowserAccessibilityManager overrides.
-  void NotifyAccessibilityEvent(ui::AXEvent event_type,
-                                BrowserAccessibility* node) override;
+  void NotifyAccessibilityEvent(
+      BrowserAccessibilityEvent::Source source,
+      ui::AXEvent event_type,
+      BrowserAccessibility* node) override;
   void SendLocationChangeEvents(
       const std::vector<AccessibilityHostMsg_LocationChangeParams>& params)
           override;
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
index 72dbdfd..bb67bc9 100644
--- a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -50,6 +50,7 @@
 }
 
 void BrowserAccessibilityManagerAuraLinux::NotifyAccessibilityEvent(
+    BrowserAccessibilityEvent::Source source,
     ui::AXEvent event_type,
     BrowserAccessibility* node) {
   // TODO(shreeram.k) : Implement.
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.h b/content/browser/accessibility/browser_accessibility_manager_auralinux.h
index 4ccd31f..36c983e 100644
--- a/content/browser/accessibility/browser_accessibility_manager_auralinux.h
+++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.h
@@ -28,8 +28,10 @@
   static ui::AXTreeUpdate GetEmptyDocument();
 
   // Implementation BrowserAccessibilityManager methods
-  void NotifyAccessibilityEvent(ui::AXEvent event_type,
-                                BrowserAccessibility* node) override;
+  void NotifyAccessibilityEvent(
+      BrowserAccessibilityEvent::Source source,
+      ui::AXEvent event_type,
+      BrowserAccessibility* node) override;
 
   AtkObject* parent_object() { return parent_object_; }
 
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.h b/content/browser/accessibility/browser_accessibility_manager_mac.h
index 715081920..74063b7 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.h
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -35,8 +35,10 @@
   BrowserAccessibility* GetFocus() override;
 
   // Implementation of BrowserAccessibilityManager.
-  void NotifyAccessibilityEvent(ui::AXEvent event_type,
-                                BrowserAccessibility* node) override;
+  void NotifyAccessibilityEvent(
+      BrowserAccessibilityEvent::Source source,
+      ui::AXEvent event_type,
+      BrowserAccessibility* node) override;
 
   void OnAccessibilityEvents(
       const std::vector<AXEventNotificationDetails>& details) override;
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 097eb44..d45e0c28e 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -141,6 +141,7 @@
 }
 
 void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
+    BrowserAccessibilityEvent::Source source,
     ui::AXEvent event_type,
     BrowserAccessibility* node) {
   if (!node->IsNative())
@@ -393,7 +394,10 @@
       static_cast<BrowserAccessibilityMac*>(GetRoot());
   if (root) {
     root->RecreateNativeObject();
-    NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, root);
+    NotifyAccessibilityEvent(
+        BrowserAccessibilityEvent::FromTreeChange,
+        ui::AX_EVENT_CHILDREN_CHANGED,
+        root);
   }
 }
 
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index b3e6613e..281d74d 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -12,6 +12,7 @@
 #include "base/command_line.h"
 #include "base/win/scoped_comptr.h"
 #include "base/win/windows_version.h"
+#include "content/browser/accessibility/browser_accessibility_event_win.h"
 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
 #include "content/browser/accessibility/browser_accessibility_win.h"
 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
@@ -88,144 +89,112 @@
   return delegate->AccessibilityGetNativeViewAccessible();
 }
 
-void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(
-    DWORD event, BrowserAccessibility* node) {
-  BrowserAccessibilityDelegate* delegate =
-      node->manager()->GetDelegateFromRootManager();
-  if (!delegate) {
-    // This line and other LOG(WARNING) lines are temporary, to debug
-    // flaky failures in DumpAccessibilityEvent* tests.
-    // http://crbug.com/440579
-    DLOG(WARNING) << "Not firing AX event because of no delegate";
-    return;
-  }
-
-  if (!node->IsNative())
-    return;
-
-  HWND hwnd = delegate->AccessibilityGetAcceleratedWidget();
-  if (!hwnd) {
-    DLOG(WARNING) << "Not firing AX event because of no hwnd";
-    return;
-  }
-
-  // Inline text boxes are an internal implementation detail, we don't
-  // expose them to Windows.
-  if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
-    return;
-
-  // It doesn't make sense to fire a REORDER event on a leaf node; that
-  // happens when the node has internal children line inline text boxes.
-  if (event == EVENT_OBJECT_REORDER && node->PlatformChildCount() == 0)
-    return;
-
-  // Pass the negation of this node's unique id in the |child_id|
-  // argument to NotifyWinEvent; the AT client will then call get_accChild
-  // on the HWND's accessibility object and pass it that same id, which
-  // we can use to retrieve the IAccessible for this node.
-  LONG child_id = -node->unique_id();
-  ::NotifyWinEvent(event, hwnd, OBJID_CLIENT, child_id);
-}
-
 void BrowserAccessibilityManagerWin::OnIAccessible2Used() {
   BrowserAccessibilityStateImpl::GetInstance()->OnScreenReaderDetected();
 }
 
 void BrowserAccessibilityManagerWin::UserIsReloading() {
-  if (GetRoot())
-    MaybeCallNotifyWinEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot());
+  if (GetRoot()) {
+    (new BrowserAccessibilityEventWin(
+        BrowserAccessibilityEvent::FromRenderFrameHost,
+        ui::AX_EVENT_NONE,
+        IA2_EVENT_DOCUMENT_RELOAD,
+        GetRoot()))->Fire();
+  }
 }
 
 void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
+    BrowserAccessibilityEvent::Source source,
     ui::AXEvent event_type,
     BrowserAccessibility* node) {
-  BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager();
-  if (!root_delegate || !root_delegate->AccessibilityGetAcceleratedWidget()) {
-    DLOG(WARNING) << "Not firing AX event because of no root_delegate or hwnd";
-    return;
+  if (event_type == ui::AX_EVENT_BLUR) {
+    // Equivalent to focus on the root.
+    event_type = ui::AX_EVENT_FOCUS;
+    node = GetRoot();
   }
 
+  if (event_type == ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED) {
+    // Fire the event on the object where the focus of the selection is.
+    int32_t focus_id = GetTreeData().sel_focus_object_id;
+    BrowserAccessibility* focus_object = GetFromID(focus_id);
+    if (focus_object) {
+      (new BrowserAccessibilityEventWin(
+          source,
+          ui::AX_EVENT_NONE,
+          IA2_EVENT_TEXT_CARET_MOVED,
+          focus_object))->Fire();
+      return;
+    }
+  }
+
+  BrowserAccessibilityManager::NotifyAccessibilityEvent(
+      source, event_type, node);
+}
+
+BrowserAccessibilityEvent::Result
+    BrowserAccessibilityManagerWin::FireWinAccessibilityEvent(
+        BrowserAccessibilityEventWin* event) {
+  const BrowserAccessibility* target = event->target();
+  ui::AXEvent event_type = event->event_type();
+  LONG win_event_type = event->win_event_type();
+
+  BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager();
+  if (!root_delegate)
+    return BrowserAccessibilityEvent::FailedBecauseFrameIsDetached;
+
+  HWND hwnd = root_delegate->AccessibilityGetAcceleratedWidget();
+  if (!hwnd)
+    return BrowserAccessibilityEvent::FailedBecauseNoWindow;
+
   // Don't fire events when this document might be stale as the user has
   // started navigating to a new document.
   if (user_is_navigating_away_)
-    return;
+    return BrowserAccessibilityEvent::DiscardedBecauseUserNavigatingAway;
 
   // Inline text boxes are an internal implementation detail, we don't
   // expose them to Windows.
-  if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
-    return;
+  if (target->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
+    return BrowserAccessibilityEvent::NotNeededOnThisPlatform;
 
-  LONG event_id = EVENT_MIN;
-  switch (event_type) {
-    case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
-      event_id = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
-      break;
-    case ui::AX_EVENT_ALERT:
-      event_id = EVENT_SYSTEM_ALERT;
-      break;
-    case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
-      event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED;
-      break;
-    case ui::AX_EVENT_BLUR:
-      // Equivalent to focus on the root.
-      event_id = EVENT_OBJECT_FOCUS;
-      node = GetRoot();
-      break;
-    case ui::AX_EVENT_CHILDREN_CHANGED:
-      event_id = EVENT_OBJECT_REORDER;
-      break;
-    case ui::AX_EVENT_FOCUS:
-      event_id = EVENT_OBJECT_FOCUS;
-      break;
-    case ui::AX_EVENT_LIVE_REGION_CHANGED:
-      if (node->GetBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY))
-        return;
-      event_id = EVENT_OBJECT_LIVEREGIONCHANGED;
-      break;
-    case ui::AX_EVENT_LOAD_COMPLETE:
-      event_id = IA2_EVENT_DOCUMENT_LOAD_COMPLETE;
-      break;
-    case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
-      event_id = EVENT_SYSTEM_SCROLLINGEND;
-      break;
-    case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
-      event_id = EVENT_SYSTEM_SCROLLINGSTART;
-      break;
-    case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
-      event_id = EVENT_OBJECT_SELECTIONWITHIN;
-      break;
-    case ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED: {
-      // Fire the event on the object where the focus of the selection is.
-      int32_t focus_id = GetTreeData().sel_focus_object_id;
-      BrowserAccessibility* focus_object = GetFromID(focus_id);
-      if (focus_object)
-        node = focus_object;
-      event_id = IA2_EVENT_TEXT_CARET_MOVED;
-      break;
-    }
-    default:
-      // Not all WebKit accessibility events result in a Windows
-      // accessibility notification.
-      break;
+  if (event_type == ui::AX_EVENT_LIVE_REGION_CHANGED &&
+      target->GetBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY))
+    return BrowserAccessibilityEvent::DiscardedBecauseLiveRegionBusy;
+
+  if (!target)
+    return BrowserAccessibilityEvent::FailedBecauseNoFocus;
+
+  event->set_target(target);
+
+  // It doesn't make sense to fire a REORDER event on a leaf node; that
+  // happens when the target has internal children inline text boxes.
+  if (win_event_type == EVENT_OBJECT_REORDER &&
+      target->PlatformChildCount() == 0) {
+    return BrowserAccessibilityEvent::NotNeededOnThisPlatform;
   }
 
-  if (!node)
-    return;
-
-  if (event_id != EVENT_MIN)
-    MaybeCallNotifyWinEvent(event_id, node);
+  // Pass the negation of this node's unique id in the |child_id|
+  // argument to NotifyWinEvent; the AT client will then call get_accChild
+  // on the HWND's accessibility object and pass it that same id, which
+  // we can use to retrieve the IAccessible for this node.
+  LONG child_id = -target->unique_id();
+  ::NotifyWinEvent(win_event_type, hwnd, OBJID_CLIENT, child_id);
 
   // If this is a layout complete notification (sent when a container scrolls)
   // and there is a descendant tracked object, send a notification on it.
   // TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
   if (event_type == ui::AX_EVENT_LAYOUT_COMPLETE &&
       tracked_scroll_object_ &&
-      tracked_scroll_object_->IsDescendantOf(node)) {
-    MaybeCallNotifyWinEvent(
-        IA2_EVENT_VISIBLE_DATA_CHANGED, tracked_scroll_object_);
+      tracked_scroll_object_->IsDescendantOf(target)) {
+    (new BrowserAccessibilityEventWin(
+        BrowserAccessibilityEvent::FromScroll,
+        ui::AX_EVENT_NONE,
+        IA2_EVENT_VISIBLE_DATA_CHANGED,
+        tracked_scroll_object_))->Fire();
     tracked_scroll_object_->Release();
     tracked_scroll_object_ = NULL;
   }
+
+  return BrowserAccessibilityEvent::Sent;
 }
 
 bool BrowserAccessibilityManagerWin::CanFireEvents() {
@@ -237,15 +206,18 @@
 }
 
 void BrowserAccessibilityManagerWin::FireFocusEvent(
+    BrowserAccessibilityEvent::Source source,
     BrowserAccessibility* node) {
   // On Windows, we always fire a FOCUS event on the root of a frame before
   // firing a focus event within that frame.
   if (node->manager() != last_focused_manager_ &&
       node != node->manager()->GetRoot()) {
-    NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, node->manager()->GetRoot());
+    BrowserAccessibilityEvent::Create(source,
+                                      ui::AX_EVENT_FOCUS,
+                                      node->manager()->GetRoot())->Fire();
   }
 
-  BrowserAccessibilityManager::FireFocusEvent(node);
+  BrowserAccessibilityManager::FireFocusEvent(source, node);
 }
 
 void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXTree* tree,
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h
index 669db87..701526a8 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.h
+++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -15,6 +15,7 @@
 #include "ui/accessibility/platform/ax_platform_node_win.h"
 
 namespace content {
+class BrowserAccessibilityEventWin;
 class BrowserAccessibilityWin;
 
 // Manages a tree of BrowserAccessibilityWin objects.
@@ -37,18 +38,21 @@
   // The IAccessible for the parent window.
   IAccessible* GetParentIAccessible();
 
-  // Calls NotifyWinEvent if the parent window's IAccessible pointer is known.
-  void MaybeCallNotifyWinEvent(DWORD event, BrowserAccessibility* node);
-
   // IAccessible2UsageObserver
   void OnIAccessible2Used() override;
 
   // BrowserAccessibilityManager methods
   void UserIsReloading() override;
   void NotifyAccessibilityEvent(
-      ui::AXEvent event_type, BrowserAccessibility* node) override;
+      BrowserAccessibilityEvent::Source source,
+      ui::AXEvent event_type,
+      BrowserAccessibility* node) override;
+  BrowserAccessibilityEvent::Result
+      FireWinAccessibilityEvent(BrowserAccessibilityEventWin* event);
   bool CanFireEvents() override;
-  void FireFocusEvent(BrowserAccessibility* node) override;
+  void FireFocusEvent(
+      BrowserAccessibilityEvent::Source source,
+      BrowserAccessibility* node) override;
 
   // Track this object and post a VISIBLE_DATA_CHANGED notification when
   // its container scrolls.
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index 2ee1691b8..73f13ec 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -16,6 +16,7 @@
 #include "base/win/enum_variant.h"
 #include "base/win/scoped_comptr.h"
 #include "base/win/windows_version.h"
+#include "content/browser/accessibility/browser_accessibility_event_win.h"
 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
 #include "content/common/accessibility_messages.h"
@@ -3493,31 +3494,31 @@
 }
 
 void BrowserAccessibilityWin::UpdateStep3FireEvents(bool is_subtree_creation) {
-  BrowserAccessibilityManagerWin* manager =
-      this->manager()->ToBrowserAccessibilityManagerWin();
-
   // Fire an event when an alert first appears.
   if (ia_role() == ROLE_SYSTEM_ALERT &&
       old_win_attributes_->ia_role != ROLE_SYSTEM_ALERT) {
-    manager->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, this);
+    BrowserAccessibilityEvent::Create(
+        BrowserAccessibilityEvent::FromTreeChange,
+        ui::AX_EVENT_ALERT,
+        this)->Fire();
   }
 
   // Fire an event when a new subtree is created.
   if (is_subtree_creation)
-    manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SHOW, this);
+    FireNativeEvent(EVENT_OBJECT_SHOW);
 
   // The rest of the events only fire on changes, not on new objects.
   if (old_win_attributes_->ia_role != 0 ||
       !old_win_attributes_->role_name.empty()) {
     // Fire an event if the name, description, help, or value changes.
     if (name() != old_win_attributes_->name)
-      manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, this);
+      FireNativeEvent(EVENT_OBJECT_NAMECHANGE);
     if (description() != old_win_attributes_->description)
-      manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_DESCRIPTIONCHANGE, this);
+      FireNativeEvent(EVENT_OBJECT_DESCRIPTIONCHANGE);
     if (value() != old_win_attributes_->value)
-      manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_VALUECHANGE, this);
+      FireNativeEvent(EVENT_OBJECT_VALUECHANGE);
     if (ia_state() != old_win_attributes_->ia_state)
-      manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_STATECHANGE, this);
+      FireNativeEvent(EVENT_OBJECT_STATECHANGE);
 
     // Normally focus events are handled elsewhere, however
     // focus for managed descendants is platform-specific.
@@ -3528,7 +3529,7 @@
         (ia_state() & STATE_SYSTEM_SELECTABLE) &&
         (ia_state() & STATE_SYSTEM_FOCUSED) &&
         !(old_win_attributes_->ia_state & STATE_SYSTEM_FOCUSED)) {
-      manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_FOCUS, this);
+      FireNativeEvent(EVENT_OBJECT_FOCUS);
     }
 
     // Handle selection being added or removed.
@@ -3543,13 +3544,13 @@
       if (multiselect) {
         // In a multi-select box, fire SELECTIONADD and SELECTIONREMOVE events.
         if (is_selected_now && !was_selected_before) {
-          manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONADD, this);
+          FireNativeEvent(EVENT_OBJECT_SELECTIONADD);
         } else if (!is_selected_now && was_selected_before) {
-          manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, this);
+          FireNativeEvent(EVENT_OBJECT_SELECTIONREMOVE);
         }
       } else if (is_selected_now && !was_selected_before) {
         // In a single-select box, only fire SELECTION events.
-        manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTION, this);
+        FireNativeEvent(EVENT_OBJECT_SELECTION);
       }
     }
 
@@ -3559,7 +3560,7 @@
     if (GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) &&
         GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) {
       if (sx != previous_scroll_x_ || sy != previous_scroll_y_)
-        manager->MaybeCallNotifyWinEvent(EVENT_SYSTEM_SCROLLINGEND, this);
+        FireNativeEvent(EVENT_SYSTEM_SCROLLINGEND);
       previous_scroll_x_ = sx;
       previous_scroll_y_ = sy;
     }
@@ -3570,12 +3571,12 @@
     if (old_len > 0) {
       // In-process screen readers may call IAccessibleText::get_oldText
       // in reaction to this event to retrieve the text that was removed.
-      manager->MaybeCallNotifyWinEvent(IA2_EVENT_TEXT_REMOVED, this);
+      FireNativeEvent(IA2_EVENT_TEXT_REMOVED);
     }
     if (new_len > 0) {
       // In-process screen readers may call IAccessibleText::get_newText
       // in reaction to this event to retrieve the text that was inserted.
-      manager->MaybeCallNotifyWinEvent(IA2_EVENT_TEXT_INSERTED, this);
+      FireNativeEvent(IA2_EVENT_TEXT_INSERTED);
     }
 
     // Changing a static text node can affect the IAccessibleText hypertext
@@ -3597,8 +3598,7 @@
 }
 
 void BrowserAccessibilityWin::OnSubtreeWillBeDeleted() {
-  manager()->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent(
-      EVENT_OBJECT_HIDE, this);
+  FireNativeEvent(EVENT_OBJECT_HIDE);
 }
 
 void BrowserAccessibilityWin::NativeAddReference() {
@@ -3614,8 +3614,7 @@
 }
 
 void BrowserAccessibilityWin::OnLocationChanged() {
-  manager()->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent(
-      EVENT_OBJECT_LOCATIONCHANGE, this);
+  FireNativeEvent(EVENT_OBJECT_LOCATIONCHANGE);
 }
 
 std::vector<base::string16> BrowserAccessibilityWin::ComputeTextAttributes()
@@ -4394,6 +4393,14 @@
   }
 }
 
+void BrowserAccessibilityWin::FireNativeEvent(LONG win_event_type) const {
+  (new BrowserAccessibilityEventWin(
+      BrowserAccessibilityEvent::FromTreeChange,
+      ui::AX_EVENT_NONE,
+      win_event_type,
+      this))->Fire();
+}
+
 void BrowserAccessibilityWin::InitRoleAndState() {
   int32_t ia_role = 0;
   int32_t ia_state = 0;
diff --git a/content/browser/accessibility/browser_accessibility_win.h b/content/browser/accessibility/browser_accessibility_win.h
index 2092a9ca..9d7dd515 100644
--- a/content/browser/accessibility/browser_accessibility_win.h
+++ b/content/browser/accessibility/browser_accessibility_win.h
@@ -888,8 +888,8 @@
   // Updates object attributes of IA2 with html attributes.
   void UpdateRequiredAttributes();
 
-  // Updates the IA2 text style attributes.
-  void UpdateTextAttributes();
+  // Fire a Windows-specific accessibility event notification on this node.
+  void FireNativeEvent(LONG win_event_type) const;
 
   struct WinAttributes {
     WinAttributes();
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
index 1fe50c0..254ebb5 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
@@ -88,6 +88,7 @@
         IOHIDElementRef axis_elements[blink::WebGamepad::axesLengthCap];
         CFIndex axis_minimums[blink::WebGamepad::axesLengthCap];
         CFIndex axis_maximums[blink::WebGamepad::axesLengthCap];
+        CFIndex axis_report_sizes[blink::WebGamepad::axesLengthCap];
       } hid;
       struct {
         XboxController* device;
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
index fe77f536..38e69b6 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
@@ -45,6 +45,18 @@
   return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
 }
 
+float NormalizeUInt8Axis(uint8_t value, uint8_t min, uint8_t max) {
+  return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
+}
+
+float NormalizeUInt16Axis(uint16_t value, uint16_t min, uint16_t max) {
+  return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
+}
+
+float NormalizeUInt32Axis(uint32_t value, uint32_t min, uint32_t max) {
+  return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
+}
+
 // http://www.usb.org/developers/hidpage
 const uint32_t kGenericDesktopUsagePage = 0x01;
 const uint32_t kGameControlsUsagePage = 0x05;
@@ -205,10 +217,6 @@
     else if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Misc) {
       uint32_t axis_index = usage - kAxisMinimumUsageNumber;
       if (axis_index < WebGamepad::axesLengthCap) {
-        associated.hid.axis_minimums[axis_index] =
-            IOHIDElementGetLogicalMin(element);
-        associated.hid.axis_maximums[axis_index] =
-            IOHIDElementGetLogicalMax(element);
         associated.hid.axis_elements[axis_index] = element;
         pad.axesLength = std::max(pad.axesLength, axis_index + 1);
       } else {
@@ -235,10 +243,6 @@
             break;
         }
         if (next_index < WebGamepad::axesLengthCap) {
-          associated.hid.axis_minimums[next_index] =
-              IOHIDElementGetLogicalMin(element);
-          associated.hid.axis_maximums[next_index] =
-              IOHIDElementGetLogicalMax(element);
           associated.hid.axis_elements[next_index] = element;
           pad.axesLength = std::max(pad.axesLength, next_index + 1);
         }
@@ -249,6 +253,26 @@
     }
   }
 
+  for (uint32_t axis_index = 0; axis_index < pad.axesLength; ++axis_index) {
+    IOHIDElementRef element = associated.hid.axis_elements[axis_index];
+    if (element != NULL) {
+      CFIndex axis_min = IOHIDElementGetLogicalMin(element);
+      CFIndex axis_max = IOHIDElementGetLogicalMax(element);
+
+      // Some HID axes report a logical range of -1 to 0 signed, which must be
+      // interpreted as 0 to -1 unsigned for correct normalization behavior.
+      if (axis_min == -1 && axis_max == 0) {
+        axis_max = -1;
+        axis_min = 0;
+      }
+
+      associated.hid.axis_minimums[axis_index] = axis_min;
+      associated.hid.axis_maximums[axis_index] = axis_max;
+      associated.hid.axis_report_sizes[axis_index] =
+          IOHIDElementGetReportSize(element);
+    }
+  }
+
   return (pad.axesLength > 0 || pad.buttonsLength > 0);
 }
 
@@ -416,9 +440,27 @@
   // Find and fill in the associated axis event, if any.
   for (size_t i = 0; i < pad.axesLength; ++i) {
     if (associated.hid.axis_elements[i] == element) {
-      pad.axes[i] = NormalizeAxis(IOHIDValueGetIntegerValue(value),
-                                  associated.hid.axis_minimums[i],
-                                  associated.hid.axis_maximums[i]);
+      CFIndex axis_min = associated.hid.axis_minimums[i];
+      CFIndex axis_max = associated.hid.axis_maximums[i];
+      CFIndex axis_value = IOHIDValueGetIntegerValue(value);
+
+      if (axis_min > axis_max) {
+        // We'll need to interpret this axis as unsigned during normalization.
+        switch (associated.hid.axis_report_sizes[i]) {
+          case 8:
+            pad.axes[i] = NormalizeUInt8Axis(axis_value, axis_min, axis_max);
+            break;
+          case 16:
+            pad.axes[i] = NormalizeUInt16Axis(axis_value, axis_min, axis_max);
+            break;
+          case 32:
+            pad.axes[i] = NormalizeUInt32Axis(axis_value, axis_min, axis_max);
+            break;
+        }
+      } else {
+        pad.axes[i] = NormalizeAxis(axis_value, axis_min, axis_max);
+      }
+
       pad.timestamp = std::max(pad.timestamp, IOHIDValueGetTimeStamp(value));
       return;
     }
diff --git a/content/common/page_messages.h b/content/common/page_messages.h
index a7f56bb8..afe62b8a 100644
--- a/content/common/page_messages.h
+++ b/content/common/page_messages.h
@@ -16,7 +16,7 @@
 
 IPC_ENUM_TRAITS_MAX_VALUE(
     PageMsg_SetZoomLevel_Command,
-    PageMsg_SetZoomLevel_Command::LAST);
+    PageMsg_SetZoomLevel_Command::LAST)
 
 // Messages sent from the browser to the renderer.
 
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 87693f25..9d475eb 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -374,6 +374,10 @@
       'browser/accessibility/browser_accessibility.h',
       'browser/accessibility/browser_accessibility_cocoa.h',
       'browser/accessibility/browser_accessibility_cocoa.mm',
+      'browser/accessibility/browser_accessibility_event.h',
+      'browser/accessibility/browser_accessibility_event.cc',
+      'browser/accessibility/browser_accessibility_event_win.h',
+      'browser/accessibility/browser_accessibility_event_win.cc',
       'browser/accessibility/browser_accessibility_mac.h',
       'browser/accessibility/browser_accessibility_mac.mm',
       'browser/accessibility/browser_accessibility_manager.cc',
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index e66c4c30..1e4fba8 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/callback.h"
 #include "base/command_line.h"
 #include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/single_thread_task_runner.h"
@@ -407,6 +408,7 @@
 
   void OnDevToolsMessage(
       int, int, const std::string& message, const std::string&) {
+    last_received_message_ = message;
     std::unique_ptr<base::DictionaryValue> root(
         static_cast<base::DictionaryValue*>(
             base::JSONReader::Read(message).release()));
@@ -427,12 +429,15 @@
     return result;
   }
 
+  std::string LastReceivedMessage() const { return last_received_message_; }
+
  private:
   DevToolsAgent* agent() {
     return frame()->devtools_agent();
   }
 
   std::vector<std::string> notifications_;
+  std::string last_received_message_;
 };
 
 class RenderViewImplBlinkSettingsTest : public RenderViewImplTest {
@@ -2404,4 +2409,56 @@
   EXPECT_EQ(2, CountNotifications("Runtime.executionContextCreated"));
 }
 
+TEST_F(DevToolsAgentTest, RuntimeEvaluateRunMicrotasks) {
+  LoadHTML("<body>page</body>");
+  Attach();
+  DispatchDevToolsMessage("Console.enable",
+                          "{\"id\":1,\"method\":\"Console.enable\"}");
+  DispatchDevToolsMessage("Runtime.evaluate",
+                          "{\"id\":2,"
+                          "\"method\":\"Runtime.evaluate\","
+                          "\"params\":{"
+                          "\"expression\":\"Promise.resolve().then("
+                          "() => console.log(42));\""
+                          "}"
+                          "}");
+  EXPECT_EQ(1, CountNotifications("Console.messageAdded"));
+}
+
+TEST_F(DevToolsAgentTest, RuntimeCallFunctionOnRunMicrotasks) {
+  LoadHTML("<body>page</body>");
+  Attach();
+  DispatchDevToolsMessage("Console.enable",
+                          "{\"id\":1,\"method\":\"Console.enable\"}");
+  DispatchDevToolsMessage("Runtime.evaluate",
+                          "{\"id\":2,"
+                          "\"method\":\"Runtime.evaluate\","
+                          "\"params\":{"
+                          "\"expression\":\"window\""
+                          "}"
+                          "}");
+
+  std::unique_ptr<base::DictionaryValue> root(
+      static_cast<base::DictionaryValue*>(
+          base::JSONReader::Read(LastReceivedMessage()).release()));
+  const base::Value* object_id;
+  ASSERT_TRUE(root->Get("result.result.objectId", &object_id));
+  std::string object_id_str;
+  EXPECT_TRUE(base::JSONWriter::Write(*object_id, &object_id_str));
+
+  DispatchDevToolsMessage("Runtime.callFunctionOn",
+                          "{\"id\":3,"
+                          "\"method\":\"Runtime.callFunctionOn\","
+                          "\"params\":{"
+                          "\"objectId\":" +
+                              object_id_str +
+                              ","
+                              "\"functionDeclaration\":\"function foo(){ "
+                              "Promise.resolve().then(() => "
+                              "console.log(239))}\""
+                              "}"
+                              "}");
+  EXPECT_EQ(1, CountNotifications("Console.messageAdded"));
+}
+
 }  // namespace content
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc
index 44dc0f0..c4b99f6 100644
--- a/net/quic/quic_chromium_client_session.cc
+++ b/net/quic/quic_chromium_client_session.cc
@@ -705,7 +705,7 @@
     request->OnRequestCompleteSuccess(CreateOutgoingReliableStreamImpl());
   }
 
-  if (GetNumOpenOutgoingStreams() == 0) {
+  if (GetNumOpenOutgoingStreams() == 0 && stream_factory_) {
     stream_factory_->OnIdleSession(this);
   }
 }
@@ -909,7 +909,9 @@
 }
 
 void QuicChromiumClientSession::OnPathDegrading() {
-  stream_factory_->MaybeMigrateSessionEarly(this);
+  if (stream_factory_) {
+    stream_factory_->MaybeMigrateSessionEarly(this);
+  }
 }
 
 void QuicChromiumClientSession::OnProofValid(
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 8b20266..5c6fb46 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -8623,6 +8623,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "net_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ppapi_unittests"
       },
       {
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index bd8816bd..d33534e 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -286,6 +286,7 @@
 crbug.com/498539 [ Win ] inspector/tracing/timeline-event-dispatch.html [ Failure Pass ]
 crbug.com/498539 inspector/console/console-log-syntax-error.html [ Pass Timeout ]
 crbug.com/498539 inspector/tracing/timeline-bound-function.html [ Pass Failure ]
+crbug.com/498539 virtual/threaded/inspector/tracing/timeline-bound-function.html [ Pass Failure ]
 crbug.com/498539 inspector/tracing/timeline-injected-script-eval.html [ Pass Failure ]
 crbug.com/498539 inspector/tracing/timeline-time.html [ Pass Failure Timeout ]
 crbug.com/498539 inspector/tracing/timeline-timer.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-doesnt-step-into-injected-script-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-doesnt-step-into-injected-script-expected.txt
new file mode 100644
index 0000000..eab57bfa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-doesnt-step-into-injected-script-expected.txt
@@ -0,0 +1,19 @@
+Check that stepInto at then end of the script go to next user script instead InjectedScriptSource.js.
+Stack trace:
+boo:0:38
+:0:50
+
+Perform stepInto
+Stack trace:
+boo:0:48
+:0:50
+
+Perform stepInto
+Stack trace:
+:0:51
+
+Perform stepInto
+Stack trace:
+foo:5:12
+
+
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-doesnt-step-into-injected-script.html b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-doesnt-step-into-injected-script.html
new file mode 100644
index 0000000..fb092b0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-doesnt-step-into-injected-script.html
@@ -0,0 +1,39 @@
+<html>
+<head>
+<script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-protocol-test.js"></script>
+<script>
+
+function foo()
+{
+    return 239;
+}
+
+function test()
+{
+    InspectorTest.sendCommandOrDie("Debugger.enable", {});
+    InspectorTest.eventHandler["Debugger.paused"] = debuggerPaused;
+    InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "(function boo() { setTimeout(foo, 0); debugger; })()" });
+
+    var actions = [ "stepInto", "stepInto", "stepInto" ];
+    function debuggerPaused(result)
+    {
+        InspectorTest.log("Stack trace:");
+        for (var callFrame of result.params.callFrames)
+            InspectorTest.log(callFrame.functionName + ':' + callFrame.location.lineNumber + ":" + callFrame.location.columnNumber);
+        InspectorTest.log("");
+
+        var action = actions.shift();
+        if (!action) {
+            InspectorTest.sendCommandOrDie("Debugger.resume", {}, () => InspectorTest.completeTest());
+            return;
+        }
+        InspectorTest.log("Perform " + action);
+        InspectorTest.sendCommandOrDie("Debugger." + action, {});
+    }
+}
+</script>
+</head>
+<body onLoad="runTest();">
+Check that stepInto at then end of the script go to next user script instead InjectedScriptSource.js.
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-doesnt-run-microtasks-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-doesnt-run-microtasks-expected.txt
new file mode 100644
index 0000000..c8cb3dcb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-doesnt-run-microtasks-expected.txt
@@ -0,0 +1,25 @@
+CONSOLE MESSAGE: line 9: 42
+CONSOLE MESSAGE: line 10: 43
+CONSOLE MESSAGE: line 8: 239
+CONSOLE MESSAGE: line 1: finished
+Check that console.log doesn't run microtasks.
+{
+    description : 42
+    type : number
+    value : 42
+}
+{
+    description : 43
+    type : number
+    value : 43
+}
+{
+    description : 239
+    type : number
+    value : 239
+}
+{
+    type : string
+    value : finished
+}
+
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-doesnt-run-microtasks.html b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-doesnt-run-microtasks.html
new file mode 100644
index 0000000..73aa542e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-console-log-doesnt-run-microtasks.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+<script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-protocol-test.js"></script>
+<script>
+
+function testFunction()
+{
+    Promise.resolve().then(function(){ console.log(239); });
+    console.log(42);
+    console.log(43);
+}
+
+function test()
+{
+    InspectorTest.sendCommandOrDie("Console.enable", {});
+    InspectorTest.eventHandler["Console.messageAdded"] = messageAdded;
+    InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "testFunction()" });
+    InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "setTimeout(() => console.log(\"finished\"), 0)" });
+
+    function messageAdded(result)
+    {
+        InspectorTest.logObject(result.params.message.parameters[0]);
+        if (result.params.message.parameters[0].value === "finished")
+            InspectorTest.completeTest();
+    }
+}
+</script>
+</head>
+<body onLoad="runTest();">
+Check that console.log doesn't run microtasks.
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-custom-formatters-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-custom-formatters-expected.txt
index dc1bd2b..77b99b856 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-custom-formatters-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-custom-formatters-expected.txt
@@ -2,8 +2,8 @@
 CONSOLE MESSAGE: line 124: [object Object]
 CONSOLE MESSAGE: line 125: [object Object]
 CONSOLE MESSAGE: line 126: [object Object]
-CONSOLE ERROR: line 127: Custom Formatter Failed: Too deep hierarchy of inlined custom previews
 CONSOLE MESSAGE: line 127: [object Object]
+CONSOLE ERROR: Custom Formatter Failed: Too deep hierarchy of inlined custom previews
 Tests that console logging dumps properly when there are multiple custom formatters on the page
 
 console-custom-formatters.html:123 Header formatted by 1 aBody formatted by 1 a
@@ -11,5 +11,5 @@
 console-custom-formatters.html:125 Header formatted by 1 cBody formatted by 1 c
 console-custom-formatters.html:126 Formatter with config Header info: additional infobodyinfo: additional info
 console-custom-formatters.html:127 Formatter with config Formatter with config Formatter with config Formatter with config Formatter with config Formatter with config Formatter with config Formatter with config Formatter with config Object
-console-custom-formatters.html:127 Custom Formatter Failed: Too deep hierarchy of inlined custom previews undefinedlogVars @ console-custom-formatters.html:127(anonymous function) @ VM:1
+Custom Formatter Failed: Too deep hierarchy of inlined custom previews undefined
 
diff --git a/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md b/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md
index e946a05..21a150b 100644
--- a/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md
+++ b/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md
@@ -335,8 +335,10 @@
 The function implementation must contain:
 
 *   For each on-heap object `m_object` in your class, a tracing call: "```visitor->trace(m_object);```".
+*   If your class has one or more weak references (`WeakMember<T>`), you have the option of
+    registering a *weak callback* for the object. See details below for how.
 *   For each base class of your class `BaseClass` that is a descendant of `GarbageCollected<T>` or
-    `GarbageCollectedMixin`, delegation call to base class: "```BaseClass::trace(visitor);```"
+    `GarbageCollectedMixin`, a delegation call to base class: "```BaseClass::trace(visitor);```"
 
 It is recommended that the delegation call, if any, is put at the end of a tracing method.
 
@@ -382,4 +384,43 @@
 }
 ```
 
+Given that the class `C` above contained a `WeakMember<Y>` field, you could alternatively
+register a *weak callback* in the trace method, and have it be invoked after the marking
+phase:
+
+```c++
+
+void C::clearWeakMembers(Visitor* visitor)
+{
+    if (ThreadHeap::isHeapObjectAlive(m_y))
+        return;
+
+    // |m_y| is not referred to by anyone else, clear the weak
+    // reference along with updating state / clearing any other
+    // resources at the same time. None of those operations are
+    // allowed to perform heap allocations:
+    m_y->detach();
+
+    // Note: if the weak callback merely clears the weak reference,
+    // it is much simpler to just |trace| the field rather than
+    // install a custom weak callback.
+    m_y = nullptr;
+}
+
+DEFINE_TRACE(C)
+{
+    visitor->template registerWeakMembers<C, &C::clearWeakMembers>(this);
+    visitor->trace(m_x);
+    visitor->trace(m_z); // Heap collection does, too.
+    B::trace(visitor); // Delegate to the parent. In this case it's empty, but this is required.
+}
+```
+
+Please notice that if the object (of type `C`) is also not reachable, its `trace` method
+will not be invoked and any follow-on weak processing will not be done. Hence, if the
+object must always perform some operation when the weak reference is cleared, that
+needs to (also) happen during finalization.
+
+Weak callbacks have so far seen little use in Blink, but a mechanism that's available.
+
 ## Heap collections
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.cpp
index 590bb2d2..12927b4 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.cpp
@@ -84,6 +84,10 @@
 
 v8::Local<v8::Value> V8FunctionCall::callWithoutExceptionHandling()
 {
+    // TODO(dgozman): get rid of this check.
+    if (!m_debugger->client()->isExecutionAllowed())
+        return v8::Local<v8::Value>();
+
     v8::Local<v8::Object> thisObject = v8::Local<v8::Object>::Cast(m_value);
     v8::Local<v8::Value> value;
     if (!thisObject->Get(m_context, m_name).ToLocal(&value))
@@ -98,8 +102,9 @@
         ASSERT(!info[i].IsEmpty());
     }
 
+    v8::MicrotasksScope microtasksScope(m_context->GetIsolate(), v8::MicrotasksScope::kDoNotRunMicrotasks);
     v8::Local<v8::Value> result;
-    if (!m_debugger->callFunction(function, m_context, thisObject, m_arguments.size(), info.get()).ToLocal(&result))
+    if (!function->Call(m_context, thisObject, m_arguments.size(), info.get()).ToLocal(&result))
         return v8::Local<v8::Value>();
     return result;
 }
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
index 6822775..dac95be1 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
@@ -107,7 +107,12 @@
     // Temporarily enable allow evals for inspector.
     if (evalIsDisabled)
         scope.context()->AllowCodeGenerationFromStrings(true);
-    v8::MaybeLocal<v8::Value> maybeResultValue = m_debugger->compileAndRunInternalScript(scope.context(), toV8String(m_debugger->isolate(), expression));
+
+    v8::MaybeLocal<v8::Value> maybeResultValue;
+    v8::Local<v8::Script> script = m_debugger->compileInternalScript(scope.context(), toV8String(m_debugger->isolate(), expression), String16());
+    if (!script.IsEmpty())
+        maybeResultValue = m_debugger->runCompiledScript(scope.context(), script);
+
     if (evalIsDisabled)
         scope.context()->AllowCodeGenerationFromStrings(false);
 
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index dbce5b0..fb8766c 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -4275,8 +4275,13 @@
         devTools->layerTreeViewChanged(m_layerTreeView);
 
     m_page->settings().setAcceleratedCompositingEnabled(m_layerTreeView);
-    if (m_layerTreeView)
+    if (m_layerTreeView) {
         m_page->layerTreeViewInitialized(*m_layerTreeView);
+        // We don't yet have a page loaded at this point of the initialization of WebViewImpl.
+        // Suppress commits until Blink generates invalidations so we don't
+        // attempt to paint too early in the next page load.
+        m_layerTreeView->setDeferCommits(true);
+    }
 
     // FIXME: only unittests, click to play, Android printing, and printing (for headers and footers)
     // make this assert necessary. We should make them not hit this code and then delete allowsBrokenNullLayerTreeView.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
index b2fa663..f282e81 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
@@ -500,6 +500,9 @@
         # from a file url for results.html and Chromium doesn't allow that.
         json_results_generator.write_json(self._filesystem, summarized_failing_results, full_results_path, callback="ADD_RESULTS")
 
+        if self._options.json_test_results:
+            json_results_generator.write_json(self._filesystem, summarized_failing_results, self._options.json_test_results)
+
         _log.debug("Finished writing JSON files.")
 
     def _upload_json_files(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
index 8af17125..3e78d65 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -164,6 +164,10 @@
                 default=False,
                 help="Show all failures in results.html, rather than only regressions"),
             optparse.make_option(
+                "--json-test-results",
+                action="store",
+                help="Path to write the JSON test results to."),
+            optparse.make_option(
                 "--new-baseline",
                 action="store_true",
                 default=False,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
index fd1d7c4a..e5be517 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -196,7 +196,9 @@
         self.should_test_processes = not self._platform.is_win()
 
     def test_basic(self):
-        options, args = parse_args(tests_included=True)
+        options, args = parse_args(
+            extra_args=['--json-test-results', '/tmp/json_test_results.json'],
+            tests_included=True)
         logging_stream = StringIO.StringIO()
         stdout = StringIO.StringIO()
         host = MockHost()
@@ -231,6 +233,9 @@
         json_to_eval = failing_results_text.replace("ADD_RESULTS(", "").replace(");", "")
         self.assertEqual(json.loads(json_to_eval), details.summarized_failing_results)
 
+        json_test_results = host.filesystem.read_text_file('/tmp/json_test_results.json')
+        self.assertEqual(json.loads(json_test_results), details.summarized_failing_results)
+
         full_results_text = host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json')
         self.assertEqual(json.loads(full_results_text), details.summarized_full_results)