diff --git a/DEPS b/DEPS
index d01b2ad..3943625 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'e7365065acfe1fc6abbeb248fd5cc0ca83d9d341',
+  'skia_revision': '82b043e87380a64ea4ca736b293ec0ee5c30e676',
   # 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': '167dc63b4c9a1d0f0fe1b19af93644ac9a561e83',
+  'v8_revision': '1eed63095df9422c5633d215bd73792695a3e377',
   # 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/cc/input/input_handler.h b/cc/input/input_handler.h
index 7115b31..30ac88d 100644
--- a/cc/input/input_handler.h
+++ b/cc/input/input_handler.h
@@ -100,12 +100,9 @@
     uint32_t main_thread_scrolling_reasons;
   };
 
-  // TODO(ymalik): Remove ANIMATED_WHEEL once it is no longer special cased.
-  // see crbug.com/575019.
   enum ScrollInputType {
     TOUCHSCREEN,
     WHEEL,
-    ANIMATED_WHEEL,
     NON_BUBBLING_GESTURE
   };
 
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index a993e6e..651fe18 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -141,7 +141,7 @@
 }
 
 bool IsWheelBasedScroll(InputHandler::ScrollInputType type) {
-  return type == InputHandler::WHEEL || type == InputHandler::ANIMATED_WHEEL;
+  return type == InputHandler::WHEEL;
 }
 
 enum ScrollThread { MAIN_THREAD, CC_THREAD };
@@ -2705,9 +2705,9 @@
 
   // ScrollAnimated is used for animated wheel scrolls. We find the first layer
   // that can scroll and set up an animation of its scroll offset. Note that
-  // this does not currently go through the scroll customization and viewport
-  // machinery that ScrollBy uses for non-animated wheel scrolls.
-  scroll_status = ScrollBegin(&scroll_state, ANIMATED_WHEEL);
+  // this does not currently go through the scroll customization machinery
+  // that ScrollBy uses for non-animated wheel scrolls.
+  scroll_status = ScrollBegin(&scroll_state, WHEEL);
   scroll_node = scroll_tree.CurrentlyScrollingNode();
   if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
     ScrollStateData scroll_state_end_data;
@@ -2799,9 +2799,9 @@
 
   // ScrollAnimated is used for animated wheel scrolls. We find the first layer
   // that can scroll and set up an animation of its scroll offset. Note that
-  // this does not currently go through the scroll customization and viewport
-  // machinery that ScrollBy uses for non-animated wheel scrolls.
-  scroll_status = ScrollBegin(&scroll_state, ANIMATED_WHEEL);
+  // this does not currently go through the scroll customization machinery
+  // that ScrollBy uses for non-animated wheel scrolls.
+  scroll_status = ScrollBegin(&scroll_state, WHEEL);
   scroll_node = scroll_tree.CurrentlyScrollingNode();
   if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
     gfx::Vector2dF pending_delta = scroll_delta;
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 20b5060f..ee4ac60 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -246,10 +246,6 @@
 #   define SK_SUPPORT_LEGACY_PEEKPIXELS_PARMS
 #endif
 
-#ifndef    SK_SUPPORT_LEGACY_SETSHADER_PTR
-#   define SK_SUPPORT_LEGACY_SETSHADER_PTR
-#endif
-
 #ifndef    SK_SUPPORT_LEGACY_TYPEFACE_PTR
 #   define SK_SUPPORT_LEGACY_TYPEFACE_PTR
 #endif
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
index 821b3de..2210928 100644
--- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -122,9 +122,9 @@
     case ChromeClient::PromptDialog:
         return "prompt";
     case ChromeClient::HTMLDialog:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return "";
 }
 
@@ -140,9 +140,9 @@
     case Document::UnloadDismissal:
         return "unload";
     case Document::NoDismissal:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return "";
 }
 
diff --git a/third_party/WebKit/Source/web/DateTimeChooserImpl.cpp b/third_party/WebKit/Source/web/DateTimeChooserImpl.cpp
index e6b5fa9..3705d22 100644
--- a/third_party/WebKit/Source/web/DateTimeChooserImpl.cpp
+++ b/third_party/WebKit/Source/web/DateTimeChooserImpl.cpp
@@ -99,7 +99,7 @@
     else if (type == InputTypeNames::week)
         components.setMillisecondsSinceEpochForWeek(value);
     else
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     return components.getType() == DateComponents::Invalid ? String() : components.toString();
 }
 
diff --git a/third_party/WebKit/Source/web/LocalFileSystemClient.cpp b/third_party/WebKit/Source/web/LocalFileSystemClient.cpp
index a48522c..a09120b 100644
--- a/third_party/WebKit/Source/web/LocalFileSystemClient.cpp
+++ b/third_party/WebKit/Source/web/LocalFileSystemClient.cpp
@@ -55,7 +55,7 @@
 {
     DCHECK(context);
     if (context->isDocument()) {
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         return false;
     }
 
@@ -67,7 +67,7 @@
 {
     DCHECK(context);
     if (!context->isDocument()) {
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         return;
     }
 
diff --git a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
index e2c41392..65a6501 100644
--- a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
+++ b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
@@ -254,7 +254,7 @@
         WEBINPUT_EVENT_CASE(TouchEnd)
         WEBINPUT_EVENT_CASE(TouchCancel)
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         return "";
     }
 }
diff --git a/third_party/WebKit/Source/web/PopupMenuImpl.cpp b/third_party/WebKit/Source/web/PopupMenuImpl.cpp
index 83346701..3d2a8dd 100644
--- a/third_party/WebKit/Source/web/PopupMenuImpl.cpp
+++ b/third_party/WebKit/Source/web/PopupMenuImpl.cpp
@@ -52,7 +52,7 @@
     case FontWeight900:
         return "900";
     }
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return nullptr;
 }
 
@@ -64,7 +64,7 @@
     case FontVariantSmallCaps:
         return "small-caps";
     }
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return nullptr;
 }
 
@@ -80,7 +80,7 @@
     case FontStyleItalic:
         return "italic";
     }
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return nullptr;
 }
 
@@ -96,7 +96,7 @@
     case TTNONE:
         return "none";
     }
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return "";
 }
 
diff --git a/third_party/WebKit/Source/web/WebDOMFileSystem.cpp b/third_party/WebKit/Source/web/WebDOMFileSystem.cpp
index 3fb40013..ae2cf1a 100644
--- a/third_party/WebKit/Source/web/WebDOMFileSystem.cpp
+++ b/third_party/WebKit/Source/web/WebDOMFileSystem.cpp
@@ -105,7 +105,7 @@
     case FileSystemTypeExternal:
         return WebFileSystem::TypeExternal;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         return WebFileSystem::TypeTemporary;
     }
 }
diff --git a/third_party/WebKit/Source/web/WebFrameSerializerImpl.cpp b/third_party/WebKit/Source/web/WebFrameSerializerImpl.cpp
index d5331af..42c412bb 100644
--- a/third_party/WebKit/Source/web/WebFrameSerializerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameSerializerImpl.cpp
@@ -427,7 +427,7 @@
     case Node::DOCUMENT_NODE:
     case Node::DOCUMENT_FRAGMENT_NODE:
         // Should not exist.
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         break;
     // Document type node can be in DOM?
     case Node::DOCUMENT_TYPE_NODE:
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
index 349ff5f..be7f985 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -256,7 +256,7 @@
 void WebFrameWidgetImpl::paint(WebCanvas* canvas, const WebRect& rect)
 {
     // Out-of-process iframes require compositing.
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 
@@ -361,7 +361,7 @@
             gestureIndicator = adoptPtr(new UserGestureIndicator(m_mouseCaptureGestureToken.release()));
             break;
         default:
-            ASSERT_NOT_REACHED();
+            NOTREACHED();
         }
 
         node->dispatchMouseEvent(
@@ -750,7 +750,7 @@
         m_client->didHandleGestureEvent(event, eventCancelled);
         return WebInputEventResult::NotHandled;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
     LocalFrame* frame = m_localRoot->frame();
     eventResult = frame->eventHandler().handleGestureEvent(PlatformGestureEventBuilder(frame->view(), event));
diff --git a/third_party/WebKit/Source/web/WebIDBKey.cpp b/third_party/WebKit/Source/web/WebIDBKey.cpp
index 911a2c0..a2f5323 100644
--- a/third_party/WebKit/Source/web/WebIDBKey.cpp
+++ b/third_party/WebKit/Source/web/WebIDBKey.cpp
@@ -116,7 +116,7 @@
             break;
         case WebIDBKeyTypeNull:
         case WebIDBKeyTypeMin:
-            ASSERT_NOT_REACHED();
+            NOTREACHED();
             break;
         }
     }
@@ -150,7 +150,7 @@
             keys[i] = WebIDBKey::createInvalid();
             break;
         case IDBKey::MinType:
-            ASSERT_NOT_REACHED();
+            NOTREACHED();
             break;
         }
     }
diff --git a/third_party/WebKit/Source/web/WebInputEventConversion.cpp b/third_party/WebKit/Source/web/WebInputEventConversion.cpp
index 881250c..b020b0f 100644
--- a/third_party/WebKit/Source/web/WebInputEventConversion.cpp
+++ b/third_party/WebKit/Source/web/WebInputEventConversion.cpp
@@ -115,7 +115,7 @@
     case WebGestureEvent::ScrollUnits::Page:
         return ScrollGranularity::ScrollByPage;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         return ScrollGranularity::ScrollByPrecisePixel;
     }
 }
@@ -130,7 +130,7 @@
     case ScrollGranularity::ScrollByPage:
         return WebGestureEvent::ScrollUnits::Page;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         return WebGestureEvent::ScrollUnits::PrecisePixels;
     }
 }
@@ -176,7 +176,7 @@
         break;
 
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
 }
 
@@ -271,7 +271,7 @@
         // DoubleTap gesture is now handled as PlatformEvent::GestureTap with tap_count = 2. So no
         // need to convert to a Platfrom DoubleTap gesture. But in WebViewImpl::handleGestureEvent
         // all WebGestureEvent are converted to PlatformGestureEvent, for completeness and not reach
-        // the ASSERT_NOT_REACHED() at the end, convert the DoubleTap to a NoType.
+        // the NOTREACHED() at the end, convert the DoubleTap to a NoType.
         m_type = PlatformEvent::NoType;
         break;
     case WebInputEvent::GestureTwoFingerTap:
@@ -297,7 +297,7 @@
         m_data.m_pinchUpdate.m_scale = e.data.pinchUpdate.scale;
         break;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
     m_position = widget->convertFromRootFrame(flooredIntPoint(convertHitPointToRootFrame(widget, FloatPoint(e.x, e.y))));
     m_globalPosition = IntPoint(e.globalX, e.globalY);
@@ -311,7 +311,7 @@
         m_source = PlatformGestureSourceTouchscreen;
         break;
     case WebGestureDeviceUninitialized:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
 }
 
@@ -329,7 +329,7 @@
     case WebInputEvent::Char:
         return PlatformEvent::Char;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
     return PlatformEvent::KeyDown;
 }
@@ -394,7 +394,7 @@
     case WebInputEvent::TouchCancel:
         return PlatformEvent::TouchCancel;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
     return PlatformEvent::TouchStart;
 }
@@ -413,7 +413,7 @@
     case WebTouchPoint::StateCancelled:
         return PlatformTouchPoint::TouchCancelled;
     case WebTouchPoint::StateUndefined:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
     return PlatformTouchPoint::TouchReleased;
 }
@@ -710,7 +710,7 @@
     else if (event.type() == EventTypeNames::touchcancel)
         type = TouchCancel;
     else {
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         type = Undefined;
         return;
     }
@@ -785,7 +785,7 @@
         sourceDevice = WebGestureDeviceTouchscreen;
         break;
     case GestureSourceUninitialized:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
 }
 
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index bdec86a..01d196b8 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -469,7 +469,7 @@
 
     void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels) override
     {
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
 
 protected:
@@ -565,7 +565,7 @@
 
 WebRemoteFrame* WebLocalFrameImpl::toWebRemoteFrame()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return 0;
 }
 
@@ -611,7 +611,7 @@
 
 void WebLocalFrameImpl::setRemoteWebLayer(WebLayer* webLayer)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebLocalFrameImpl::setContentSettingsClient(WebContentSettingsClient* contentSettingsClient)
@@ -770,7 +770,7 @@
         webCoreMessageLevel = ErrorMessageLevel;
         break;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
         return;
     }
 
diff --git a/third_party/WebKit/Source/web/WebPerformance.cpp b/third_party/WebKit/Source/web/WebPerformance.cpp
index feb78fc..baeb02c 100644
--- a/third_party/WebKit/Source/web/WebPerformance.cpp
+++ b/third_party/WebKit/Source/web/WebPerformance.cpp
@@ -61,7 +61,7 @@
     case PerformanceNavigation::TYPE_RESERVED:
         return WebNavigationTypeOther;
     }
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebNavigationTypeOther;
 }
 
diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
index 6e2cc9dc..9db1f91b 100644
--- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
@@ -62,7 +62,7 @@
 
 WebLocalFrame* WebRemoteFrameImpl::toWebLocalFrame()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return nullptr;
 }
 
@@ -87,24 +87,24 @@
 
 WebString WebRemoteFrameImpl::uniqueName() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebString();
 }
 
 WebString WebRemoteFrameImpl::assignedName() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebString();
 }
 
 void WebRemoteFrameImpl::setName(const WebString&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 WebVector<WebIconURL> WebRemoteFrameImpl::iconURLs(int iconTypesMask) const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebVector<WebIconURL>();
 }
 
@@ -118,52 +118,52 @@
 
 void WebRemoteFrameImpl::setSharedWorkerRepositoryClient(WebSharedWorkerRepositoryClient*)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::setCanHaveScrollbars(bool)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 WebSize WebRemoteFrameImpl::scrollOffset() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebSize();
 }
 
 void WebRemoteFrameImpl::setScrollOffset(const WebSize&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 WebSize WebRemoteFrameImpl::contentsSize() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebSize();
 }
 
 bool WebRemoteFrameImpl::hasVisibleContent() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 WebRect WebRemoteFrameImpl::visibleContentRect() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebRect();
 }
 
 bool WebRemoteFrameImpl::hasHorizontalScrollbar() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 bool WebRemoteFrameImpl::hasVerticalScrollbar() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
@@ -183,57 +183,57 @@
 
 WebPerformance WebRemoteFrameImpl::performance() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebPerformance();
 }
 
 bool WebRemoteFrameImpl::dispatchBeforeUnloadEvent()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 void WebRemoteFrameImpl::dispatchUnloadEvent()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::executeScript(const WebScriptSource&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::executeScriptInIsolatedWorld(
     int worldID, const WebScriptSource* sources, unsigned numSources,
     int extensionGroup)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::setIsolatedWorldSecurityOrigin(int worldID, const WebSecurityOrigin&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::setIsolatedWorldContentSecurityPolicy(int worldID, const WebString&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::addMessageToConsole(const WebConsoleMessage&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::collectGarbage()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 v8::Local<v8::Value> WebRemoteFrameImpl::executeScriptAndReturnValue(
     const WebScriptSource&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return v8::Local<v8::Value>();
 }
 
@@ -241,7 +241,7 @@
     int worldID, const WebScriptSource* sourcesIn, unsigned numSources,
     int extensionGroup, WebVector<v8::Local<v8::Value>>* results)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 v8::Local<v8::Value> WebRemoteFrameImpl::callFunctionEvenIfScriptDisabled(
@@ -250,13 +250,13 @@
     int argc,
     v8::Local<v8::Value> argv[])
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return v8::Local<v8::Value>();
 }
 
 v8::Local<v8::Context> WebRemoteFrameImpl::mainWorldScriptContext() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return v8::Local<v8::Context>();
 }
 
@@ -267,29 +267,29 @@
 
 void WebRemoteFrameImpl::reload(WebFrameLoadType)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::reloadWithOverrideURL(const WebURL& overrideUrl, WebFrameLoadType)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::loadRequest(const WebURLRequest&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::loadHistoryItem(const WebHistoryItem&, WebHistoryLoadType, WebCachePolicy)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::loadHTMLString(
     const WebData& html, const WebURL& baseURL, const WebURL& unreachableURL,
     bool replace)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::stopLoading()
@@ -300,103 +300,103 @@
 
 WebDataSource* WebRemoteFrameImpl::provisionalDataSource() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return nullptr;
 }
 
 WebDataSource* WebRemoteFrameImpl::dataSource() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return nullptr;
 }
 
 void WebRemoteFrameImpl::enableViewSourceMode(bool enable)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 bool WebRemoteFrameImpl::isViewSourceModeEnabled() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 void WebRemoteFrameImpl::setReferrerForRequest(WebURLRequest&, const WebURL& referrer)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::dispatchWillSendRequest(WebURLRequest&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 WebURLLoader* WebRemoteFrameImpl::createAssociatedURLLoader(const WebURLLoaderOptions&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return nullptr;
 }
 
 unsigned WebRemoteFrameImpl::unloadListenerCount() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return 0;
 }
 
 void WebRemoteFrameImpl::insertText(const WebString&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::setMarkedText(const WebString&, unsigned location, unsigned length)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::unmarkText()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 bool WebRemoteFrameImpl::hasMarkedText() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 WebRange WebRemoteFrameImpl::markedRange() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebRange();
 }
 
 bool WebRemoteFrameImpl::firstRectForCharacterRange(unsigned location, unsigned length, WebRect&) const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 size_t WebRemoteFrameImpl::characterIndexForPoint(const WebPoint&) const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return 0;
 }
 
 bool WebRemoteFrameImpl::executeCommand(const WebString&, const WebNode&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 bool WebRemoteFrameImpl::executeCommand(const WebString&, const WebString& value, const WebNode&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 bool WebRemoteFrameImpl::isCommandEnabled(const WebString&) const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
@@ -411,124 +411,124 @@
 
 void WebRemoteFrameImpl::requestTextChecking(const WebElement&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::removeSpellingMarkers()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 bool WebRemoteFrameImpl::hasSelection() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 WebRange WebRemoteFrameImpl::selectionRange() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebRange();
 }
 
 WebString WebRemoteFrameImpl::selectionAsText() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebString();
 }
 
 WebString WebRemoteFrameImpl::selectionAsMarkup() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebString();
 }
 
 bool WebRemoteFrameImpl::selectWordAroundCaret()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 void WebRemoteFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::selectRange(const WebRange&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::moveRangeSelection(const WebPoint& base, const WebPoint& extent, WebFrame::TextGranularity granularity)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::moveCaretSelection(const WebPoint&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 bool WebRemoteFrameImpl::setEditableSelectionOffsets(int start, int end)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 bool WebRemoteFrameImpl::setCompositionFromExistingText(int compositionStart, int compositionEnd, const WebVector<WebCompositionUnderline>& underlines)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 void WebRemoteFrameImpl::extendSelectionAndDelete(int before, int after)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::setCaretVisible(bool)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 int WebRemoteFrameImpl::printBegin(const WebPrintParams&, const WebNode& constrainToNode)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return 0;
 }
 
 float WebRemoteFrameImpl::printPage(int pageToPrint, WebCanvas*)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return 0.0;
 }
 
 float WebRemoteFrameImpl::getPrintPageShrink(int page)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return 0.0;
 }
 
 void WebRemoteFrameImpl::printEnd()
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 bool WebRemoteFrameImpl::isPrintScalingDisabledForPlugin(const WebNode&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 bool WebRemoteFrameImpl::hasCustomPageSizeStyle(int pageIndex)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 bool WebRemoteFrameImpl::isPageBoxVisible(int pageIndex)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
@@ -540,42 +540,42 @@
     int& marginBottom,
     int& marginLeft)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 WebString WebRemoteFrameImpl::pageProperty(const WebString& propertyName, int pageIndex)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebString();
 }
 
 void WebRemoteFrameImpl::printPagesWithBoundaries(WebCanvas*, const WebSize&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 void WebRemoteFrameImpl::dispatchMessageEventWithOriginCheck(
     const WebSecurityOrigin& intendedTargetOrigin,
     const WebDOMEvent&)
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
 }
 
 WebRect WebRemoteFrameImpl::selectionBoundsRect() const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebRect();
 }
 
 bool WebRemoteFrameImpl::selectionStartHasSpellingMarkerFor(int from, int length) const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return false;
 }
 
 WebString WebRemoteFrameImpl::layerTreeAsText(bool showDebugInfo) const
 {
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return WebString();
 }
 
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 8489ef36..e5d845e 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -905,7 +905,7 @@
         break;
     }
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
     m_client->didHandleGestureEvent(event, eventCancelled);
     return eventResult;
@@ -2200,7 +2200,7 @@
             gestureIndicator = adoptPtr(new UserGestureIndicator(m_mouseCaptureGestureToken.release()));
             break;
         default:
-            ASSERT_NOT_REACHED();
+            NOTREACHED();
         }
 
         node->dispatchMouseEvent(
@@ -2581,7 +2581,7 @@
             else if (autocapitalize == sentences)
                 flags |= WebTextInputFlagAutocapitalizeSentences;
             else
-                ASSERT_NOT_REACHED();
+                NOTREACHED();
         }
     }
 
@@ -3515,7 +3515,7 @@
         mediaElement->setBooleanAttribute(HTMLNames::controlsAttr, action.enable);
         break;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
 }
 
@@ -3541,7 +3541,7 @@
                 plugin->plugin()->rotateView(WebPlugin::RotationType90Counterclockwise);
                 break;
             default:
-                ASSERT_NOT_REACHED();
+                NOTREACHED();
             }
         }
     }
@@ -4529,7 +4529,7 @@
         eventType = EventTypeNames::mousemove;
         break;
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
 
     const WebMouseEvent& mouseEvent = static_cast<const WebMouseEvent&>(event);
diff --git a/third_party/WebKit/Source/web/WorkerGlobalScopeProxyProviderImpl.cpp b/third_party/WebKit/Source/web/WorkerGlobalScopeProxyProviderImpl.cpp
index 91d2e7f..64703a38 100644
--- a/third_party/WebKit/Source/web/WorkerGlobalScopeProxyProviderImpl.cpp
+++ b/third_party/WebKit/Source/web/WorkerGlobalScopeProxyProviderImpl.cpp
@@ -57,7 +57,7 @@
         // support ServiceWorker in dedicated workers (http://crbug.com/371690)
         return new DedicatedWorkerMessagingProxy(worker, workerClients);
     }
-    ASSERT_NOT_REACHED();
+    NOTREACHED();
     return 0;
 }
 
diff --git a/ui/native_theme/native_theme_mac.h b/ui/native_theme/native_theme_mac.h
index 4307174..deea30e3e 100644
--- a/ui/native_theme/native_theme_mac.h
+++ b/ui/native_theme/native_theme_mac.h
@@ -16,6 +16,17 @@
  public:
   static const int kComboboxCornerRadius = 5;
 
+  // Type of gradient to use on a button background. Use HIGHLIGHTED for the
+  // default button of a window and all combobox controls, but only when the
+  // window is active.
+  enum class ButtonBackgroundType {
+    DISABLED,
+    HIGHLIGHTED,
+    NORMAL,
+    PRESSED,
+    COUNT
+  };
+
   static NativeThemeMac* instance();
 
   // Overridden from NativeTheme:
@@ -33,7 +44,8 @@
       const MenuItemExtraParams& menu_item) const override;
 
   // Creates a shader appropriate for painting the background of a button.
-  static sk_sp<SkShader> GetButtonBackgroundShader(State state, int height);
+  static sk_sp<SkShader> GetButtonBackgroundShader(ButtonBackgroundType type,
+                                                   int height);
 
  private:
   NativeThemeMac();
diff --git a/ui/native_theme/native_theme_mac.mm b/ui/native_theme/native_theme_mac.mm
index 88343f74..15186dc 100644
--- a/ui/native_theme/native_theme_mac.mm
+++ b/ui/native_theme/native_theme_mac.mm
@@ -42,6 +42,13 @@
 const SkColor kUnfocusedSelectedTextBackgroundColor =
     SkColorSetRGB(220, 220, 220);
 
+// Helper to make indexing an array by an enum class easier.
+template <class KEY, class VALUE>
+struct EnumArray {
+  VALUE& operator[](const KEY& key) { return array[static_cast<size_t>(key)]; }
+  VALUE array[static_cast<size_t>(KEY::COUNT)];
+};
+
 // On 10.6 and 10.7 there is no way to get components from system colors. Here,
 // system colors are just opaque objects that can paint themselves and otherwise
 // tell you nothing. In 10.8, some of the system color classes have incomplete
@@ -156,6 +163,10 @@
     case kColorId_LabelDisabledColor:
       return NSSystemColorToSkColor([NSColor disabledControlTextColor]);
     case kColorId_ButtonHighlightColor:
+      // Although the NSColor documentation names "selectedControlTextColor" as
+      // the color for a "text in a .. control being clicked or dragged", it
+      // remains black, and text on Yosemite-style pressed buttons is white.
+      return SK_ColorWHITE;
     case kColorId_ButtonHoverColor:
       return NSSystemColorToSkColor([NSColor selectedControlTextColor]);
 
@@ -271,8 +282,9 @@
 
 // static
 sk_sp<SkShader> NativeThemeMac::GetButtonBackgroundShader(
-    NativeTheme::State state, int height) {
-  typedef SkColor ColorByState[NativeTheme::State::kNumStates];
+    ButtonBackgroundType type,
+    int height) {
+  using ColorByState = EnumArray<ButtonBackgroundType, SkColor>;
   SkPoint gradient_points[2];
   gradient_points[0].iset(0, 0);
   gradient_points[1].iset(0, height);
@@ -280,19 +292,18 @@
   SkScalar gradient_positions[] = { 0.0, 0.38, 1.0 };
 
   ColorByState start_colors;
-  start_colors[NativeTheme::State::kDisabled] = gfx::kMaterialGrey300;
-  start_colors[NativeTheme::State::kHovered] = gfx::kMaterialBlue300;
-  start_colors[NativeTheme::State::kNormal] = gfx::kMaterialBlue300;
-  start_colors[NativeTheme::State::kPressed] = gfx::kMaterialBlue300;
+  start_colors[ButtonBackgroundType::DISABLED] = gfx::kMaterialGrey300;
+  start_colors[ButtonBackgroundType::HIGHLIGHTED] = gfx::kMaterialBlue300;
+  start_colors[ButtonBackgroundType::NORMAL] = SK_ColorWHITE;
+  start_colors[ButtonBackgroundType::PRESSED] = gfx::kMaterialBlue300;
   ColorByState end_colors;
-  end_colors[NativeTheme::State::kDisabled] = gfx::kMaterialGrey300;
-  end_colors[NativeTheme::State::kHovered] = gfx::kMaterialBlue700;
-  end_colors[NativeTheme::State::kNormal] = gfx::kMaterialBlue700;
-  end_colors[NativeTheme::State::kPressed] = gfx::kMaterialBlue700;
+  end_colors[ButtonBackgroundType::DISABLED] = gfx::kMaterialGrey300;
+  end_colors[ButtonBackgroundType::HIGHLIGHTED] = gfx::kMaterialBlue700;
+  end_colors[ButtonBackgroundType::NORMAL] = SK_ColorWHITE;
+  end_colors[ButtonBackgroundType::PRESSED] = gfx::kMaterialBlue700;
 
-  SkColor gradient_colors[] = {
-    start_colors[state], start_colors[state], end_colors[state]
-  };
+  SkColor gradient_colors[] = {start_colors[type], start_colors[type],
+                               end_colors[type]};
 
   return SkGradientShader::MakeLinear(
       gradient_points, gradient_colors, gradient_positions, 3,
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc
index f5b07e4..02fa585 100644
--- a/ui/views/controls/button/label_button.cc
+++ b/ui/views/controls/button/label_button.cc
@@ -30,12 +30,6 @@
 // The default spacing between the icon and text.
 const int kSpacing = 5;
 
-#if !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
-// Default text and shadow colors for STYLE_BUTTON.
-const SkColor kStyleButtonTextColor = SK_ColorBLACK;
-const SkColor kStyleButtonShadowColor = SK_ColorWHITE;
-#endif
-
 const gfx::FontList& GetDefaultNormalFontList() {
   static base::LazyInstance<gfx::FontList>::Leaky font_list =
       LAZY_INSTANCE_INITIALIZER;
@@ -43,6 +37,9 @@
 }
 
 const gfx::FontList& GetDefaultBoldFontList() {
+  if (!views::PlatformStyle::kDefaultLabelButtonHasBoldFont)
+    return GetDefaultNormalFontList();
+
   static base::LazyInstance<gfx::FontList>::Leaky font_list =
       LAZY_INSTANCE_INITIALIZER;
   if ((font_list.Get().GetFontStyle() & gfx::Font::BOLD) == 0) {
@@ -163,10 +160,15 @@
 
 void LabelButton::SetFontList(const gfx::FontList& font_list) {
   cached_normal_font_list_ = font_list;
-  cached_bold_font_list_ = font_list.DeriveWithStyle(
-      font_list.GetFontStyle() | gfx::Font::BOLD);
-  label_->SetFontList(is_default_ ?
-      cached_bold_font_list_ : cached_normal_font_list_);
+  if (PlatformStyle::kDefaultLabelButtonHasBoldFont) {
+    cached_bold_font_list_ =
+        font_list.DeriveWithStyle(font_list.GetFontStyle() | gfx::Font::BOLD);
+    if (is_default_) {
+      label_->SetFontList(cached_bold_font_list_);
+      return;
+    }
+  }
+  label_->SetFontList(cached_normal_font_list_);
 }
 
 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
@@ -198,9 +200,10 @@
   ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE);
   is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel);
 
-  label_->SetFontList(
-      is_default ? cached_bold_font_list_ : cached_normal_font_list_);
+  const bool bold = PlatformStyle::kDefaultLabelButtonHasBoldFont && is_default;
+  label_->SetFontList(bold ? cached_bold_font_list_ : cached_normal_font_list_);
   InvalidateLayout();
+  ResetLabelEnabledColor();
 }
 
 void LabelButton::SetStyle(ButtonStyle style) {
@@ -215,7 +218,8 @@
   SetFocusPainter(nullptr);
   SetHorizontalAlignment(gfx::ALIGN_CENTER);
   SetFocusable(true);
-  SetMinSize(gfx::Size(70, 33));
+  SetMinSize(gfx::Size(PlatformStyle::kMinLabelButtonWidth,
+                       PlatformStyle::kMinLabelButtonHeight));
 
   // Themed borders will be set once the button is added to a Widget, since that
   // provides the value of GetNativeTheme().
@@ -241,7 +245,7 @@
   Label label(GetText(), cached_normal_font_list_);
   label.SetShadows(label_->shadows());
 
-  if (style() == STYLE_BUTTON) {
+  if (style_ == STYLE_BUTTON && PlatformStyle::kDefaultLabelButtonHasBoldFont) {
     // Some text appears wider when rendered normally than when rendered bold.
     // Accommodate the widest, as buttons may show bold and shouldn't resize.
     const int current_width = label.GetPreferredSize().width();
@@ -396,6 +400,7 @@
 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
   ResetColorsFromNativeTheme();
   UpdateThemedBorder();
+  ResetLabelEnabledColor();
   // Invalidate the layout to pickup the new insets from the border.
   InvalidateLayout();
 }
@@ -440,9 +445,7 @@
 void LabelButton::StateChanged() {
   const gfx::Size previous_image_size(image_->GetPreferredSize());
   UpdateImage();
-  const SkColor color = button_state_colors_[state()];
-  if (state() != STATE_DISABLED && label_->enabled_color() != color)
-    label_->SetEnabledColor(color);
+  ResetLabelEnabledColor();
   label_->SetEnabled(state() != STATE_DISABLED);
   if (image_->GetPreferredSize() != previous_image_size)
     Layout();
@@ -467,38 +470,21 @@
     theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonDisabledColor),
   };
 
-  // Certain styles do not change text color when hovered or pressed.
-  bool constant_text_color = false;
   // Use hardcoded colors for inverted color scheme support and STYLE_BUTTON.
   if (color_utils::IsInvertedColorScheme()) {
-    constant_text_color = true;
-    colors[STATE_NORMAL] = SK_ColorWHITE;
+    colors[STATE_NORMAL] = colors[STATE_HOVERED] = colors[STATE_PRESSED] =
+        SK_ColorWHITE;
     label_->SetBackgroundColor(SK_ColorBLACK);
     label_->set_background(Background::CreateSolidBackground(SK_ColorBLACK));
     label_->SetAutoColorReadabilityEnabled(true);
     label_->SetShadows(gfx::ShadowValues());
   } else if (style() == STYLE_BUTTON) {
-    // TODO(erg): This is disabled on desktop linux because of the binary asset
-    // confusion. These details should either be pushed into ui::NativeThemeWin
-    // or should be obsoleted by rendering buttons with paint calls instead of
-    // with static assets. http://crbug.com/350498
-#if !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
-    constant_text_color = true;
-    colors[STATE_NORMAL] = kStyleButtonTextColor;
-    label_->SetBackgroundColor(theme->GetSystemColor(
-        ui::NativeTheme::kColorId_ButtonBackgroundColor));
-    label_->SetAutoColorReadabilityEnabled(false);
-    label_->SetShadows(gfx::ShadowValues(
-        1, gfx::ShadowValue(gfx::Vector2d(0, 1), 0, kStyleButtonShadowColor)));
-#endif
-    label_->set_background(NULL);
+    PlatformStyle::ApplyLabelButtonTextStyle(label_, &colors);
+    label_->set_background(nullptr);
   } else {
-    label_->set_background(NULL);
+    label_->set_background(nullptr);
   }
 
-  if (constant_text_color)
-    colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL];
-
   for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) {
     if (!explicitly_set_colors_[state]) {
       SetTextColor(static_cast<ButtonState>(state), colors[state]);
@@ -573,4 +559,13 @@
   cached_preferred_size_ = gfx::Size();
 }
 
+void LabelButton::ResetLabelEnabledColor() {
+  const SkColor color =
+      explicitly_set_colors_[state()]
+          ? button_state_colors_[state()]
+          : PlatformStyle::TextColorForButton(button_state_colors_, *this);
+  if (state() != STATE_DISABLED && label_->enabled_color() != color)
+    label_->SetEnabledColor(color);
+}
+
 }  // namespace views
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h
index a8f419c..7473342 100644
--- a/ui/views/controls/button/label_button.h
+++ b/ui/views/controls/button/label_button.h
@@ -146,7 +146,6 @@
   FRIEND_TEST_ALL_PREFIXES(LabelButtonTest, Image);
   FRIEND_TEST_ALL_PREFIXES(LabelButtonTest, LabelAndImage);
   FRIEND_TEST_ALL_PREFIXES(LabelButtonTest, FontList);
-  FRIEND_TEST_ALL_PREFIXES(LabelButtonTest, ButtonStyleIsDefaultSize);
 
   void SetTextInternal(const base::string16& text);
 
@@ -167,6 +166,11 @@
   // as false.
   void ResetCachedPreferredSize();
 
+  // Updates additional state related to focus or default status, rather than
+  // merely the CustomButton::state(). E.g. ensures the label text color is
+  // correct for the current background.
+  void ResetLabelEnabledColor();
+
   // The image and label shown in the button.
   ImageView* image_;
   Label* label_;
diff --git a/ui/views/controls/button/label_button_unittest.cc b/ui/views/controls/button/label_button_unittest.cc
index d5b6045..d036ea38 100644
--- a/ui/views/controls/button/label_button_unittest.cc
+++ b/ui/views/controls/button/label_button_unittest.cc
@@ -16,7 +16,9 @@
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/vector2d.h"
 #include "ui/gfx/text_utils.h"
+#include "ui/native_theme/native_theme.h"
 #include "ui/views/animation/button_ink_drop_delegate.h"
+#include "ui/views/style/platform_style.h"
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/test/widget_test.h"
 
@@ -34,10 +36,34 @@
 
 namespace views {
 
+// Testing button that exposes protected methods.
+class TestLabelButton : public LabelButton {
+ public:
+  TestLabelButton() : LabelButton(nullptr, base::string16()) {}
+
+  using LabelButton::label;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestLabelButton);
+};
+
 class LabelButtonTest : public test::WidgetTest {
  public:
   LabelButtonTest() {}
 
+  // Adds a LabelButton to the test Widget with the STYLE_BUTTON platform style.
+  TestLabelButton* AddStyledButton(const char* label, bool is_default) {
+    TestLabelButton* button = new TestLabelButton;
+    button->SetText(ASCIIToUTF16(label));
+    button->SetStyle(CustomButton::STYLE_BUTTON);
+    if (is_default)
+      button->SetIsDefault(true);
+    button_->GetWidget()->GetContentsView()->AddChildView(button);
+    button->SizeToPreferredSize();
+    button->Layout();
+    return button;
+  }
+
   // testing::Test:
   void SetUp() override {
     WidgetTest::SetUp();
@@ -45,8 +71,26 @@
     // used (which could be derived from the Widget's NativeTheme).
     test_widget_ = CreateTopLevelPlatformWidget();
 
-    button_ = new LabelButton(nullptr, base::string16());
+    button_ = new TestLabelButton;
     test_widget_->GetContentsView()->AddChildView(button_);
+
+    // Establish the expected text colors for testing changes due to state.
+    themed_normal_text_color_ = button_->GetNativeTheme()->GetSystemColor(
+        ui::NativeTheme::kColorId_ButtonEnabledColor);
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+    // The Linux theme provides a non-black highlight text color, but it's not
+    // used for styled buttons.
+    styled_highlight_text_color_ = themed_normal_text_color_;
+    styled_normal_text_color_ = themed_normal_text_color_;
+#else
+    styled_highlight_text_color_ = button_->GetNativeTheme()->GetSystemColor(
+        ui::NativeTheme::kColorId_ButtonHighlightColor);
+
+    // For styled buttons only, platforms other than Desktop Linux either ignore
+    // NativeTheme and use a hardcoded black or (on Mac) have a NativeTheme that
+    // reliably returns black.
+    styled_normal_text_color_ = SK_ColorBLACK;
+#endif
   }
 
   void TearDown() override {
@@ -55,7 +99,11 @@
   }
 
  protected:
-  LabelButton* button_ = nullptr;
+  TestLabelButton* button_ = nullptr;
+
+  SkColor themed_normal_text_color_ = 0;
+  SkColor styled_normal_text_color_ = 0;
+  SkColor styled_highlight_text_color_ = 0;
 
  private:
   Widget* test_widget_ = nullptr;
@@ -290,21 +338,65 @@
   EXPECT_EQ(original_width, button_->GetPreferredSize().width());
 }
 
-// Make sure the label gets the width it asks for and bolding it (via
-// SetDefault) causes the size to update. Regression test for crbug.com/578722
-TEST_F(LabelButtonTest, ButtonStyleIsDefaultSize) {
-  LabelButton* button = new LabelButton(nullptr, base::ASCIIToUTF16("Save"));
-  button->SetStyle(CustomButton::STYLE_BUTTON);
-  button_->GetWidget()->GetContentsView()->AddChildView(button);
-  button->SizeToPreferredSize();
-  button->Layout();
-  gfx::Size non_default_size = button->label_->size();
-  EXPECT_EQ(button->label_->GetPreferredSize().width(),
+// Ensure the label gets the correct style for default buttons (e.g. bolding)
+// and button size updates correctly. Regression test for crbug.com/578722.
+TEST_F(LabelButtonTest, ButtonStyleIsDefaultStyle) {
+  TestLabelButton* button = AddStyledButton("Save", false);
+  gfx::Size non_default_size = button->label()->size();
+  EXPECT_EQ(button->label()->GetPreferredSize().width(),
             non_default_size.width());
+  EXPECT_FALSE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD);
+  EXPECT_EQ(styled_normal_text_color_, button->label()->enabled_color());
   button->SetIsDefault(true);
   button->SizeToPreferredSize();
   button->Layout();
-  EXPECT_NE(non_default_size, button->label_->size());
+  EXPECT_EQ(styled_highlight_text_color_, button->label()->enabled_color());
+  if (PlatformStyle::kDefaultLabelButtonHasBoldFont) {
+    EXPECT_NE(non_default_size, button->label()->size());
+    EXPECT_TRUE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD);
+  } else {
+    EXPECT_EQ(non_default_size, button->label()->size());
+    EXPECT_FALSE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD);
+  }
+}
+
+// Ensure the label gets the correct style when pressed or becoming default.
+TEST_F(LabelButtonTest, HighlightedButtonStyle) {
+#if defined(OS_MACOSX)
+  // On Mac, ensure the normal and highlight colors are different, to ensure the
+  // tests are actually testing something. This might be the case on other
+  // platforms.
+  EXPECT_NE(styled_normal_text_color_, styled_highlight_text_color_);
+#endif
+
+  // For STYLE_TEXTBUTTON, the NativeTheme might not provide SK_ColorBLACK, but
+  // it should be the same for normal and pressed states.
+  EXPECT_EQ(themed_normal_text_color_, button_->label()->enabled_color());
+  button_->SetState(Button::STATE_PRESSED);
+  EXPECT_EQ(themed_normal_text_color_, button_->label()->enabled_color());
+
+  // Add a non-default button.
+  TestLabelButton* styled_button = AddStyledButton("OK", false);
+  EXPECT_EQ(styled_normal_text_color_, styled_button->label()->enabled_color());
+  styled_button->SetState(Button::STATE_PRESSED);
+  EXPECT_EQ(styled_highlight_text_color_,
+            styled_button->label()->enabled_color());
+
+  // If there's an explicit color set for STATE_PRESSED, that should be used.
+  styled_button->SetEnabledTextColors(SK_ColorRED);
+  EXPECT_EQ(SK_ColorRED, styled_button->label()->enabled_color());
+
+  // Test becoming default after adding to the Widget.
+  TestLabelButton* default_after = AddStyledButton("OK", false);
+  EXPECT_EQ(styled_normal_text_color_, default_after->label()->enabled_color());
+  default_after->SetIsDefault(true);
+  EXPECT_EQ(styled_highlight_text_color_,
+            default_after->label()->enabled_color());
+
+  // Test becoming default before adding to the Widget.
+  TestLabelButton* default_before = AddStyledButton("OK", true);
+  EXPECT_EQ(styled_highlight_text_color_,
+            default_before->label()->enabled_color());
 }
 
 // A ButtonInkDropDelegate that tracks the last hover state requested.
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index fcc41e81..c8166a5b 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -1030,7 +1030,10 @@
   else
     OnKeyDown(key_code);
 
-  TerminateNestedMessageLoopIfNecessary();
+  // MenuController may have been deleted, so check for an active instance
+  // before accessing member variables.
+  if (GetActiveInstance())
+    TerminateNestedMessageLoopIfNecessary();
 
   return ui::POST_DISPATCH_NONE;
 }
diff --git a/ui/views/examples/button_example.cc b/ui/views/examples/button_example.cc
index 2cf42af..02a56822 100644
--- a/ui/views/examples/button_example.cc
+++ b/ui/views/examples/button_example.cc
@@ -29,12 +29,7 @@
 namespace views {
 namespace examples {
 
-ButtonExample::ButtonExample()
-    : ExampleBase("Button"),
-      label_button_(NULL),
-      image_button_(NULL),
-      icon_(NULL),
-      count_(0) {
+ButtonExample::ButtonExample() : ExampleBase("Button") {
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   icon_ = rb.GetImageNamed(IDR_CLOSE_H).ToImageSkia();
 }
@@ -52,16 +47,14 @@
   label_button_->SetFocusable(true);
   container->AddChildView(label_button_);
 
-  LabelButton* styled_button =
-      new LabelButton(this, ASCIIToUTF16("Styled Button"));
-  styled_button->SetStyle(Button::STYLE_BUTTON);
-  container->AddChildView(styled_button);
+  styled_button_ = new LabelButton(this, ASCIIToUTF16("Styled Button"));
+  styled_button_->SetStyle(Button::STYLE_BUTTON);
+  container->AddChildView(styled_button_);
 
-  LabelButton* disabled_button =
-      new LabelButton(this, ASCIIToUTF16("Disabled Button"));
-  disabled_button->SetStyle(Button::STYLE_BUTTON);
-  disabled_button->SetState(Button::STATE_DISABLED);
-  container->AddChildView(disabled_button);
+  disabled_button_ = new LabelButton(this, ASCIIToUTF16("Disabled Button"));
+  disabled_button_->SetStyle(Button::STYLE_BUTTON);
+  disabled_button_->SetState(Button::STATE_DISABLED);
+  container->AddChildView(disabled_button_);
 
   container->AddChildView(new BlueButton(this, ASCIIToUTF16("Blue Button")));
 
@@ -88,41 +81,48 @@
   container->AddChildView(image_button_);
 }
 
-void ButtonExample::LabelButtonPressed(const ui::Event& event) {
+void ButtonExample::LabelButtonPressed(LabelButton* label_button,
+                                       const ui::Event& event) {
   PrintStatus("Label Button Pressed! count: %d", ++count_);
   if (event.IsControlDown()) {
     if (event.IsShiftDown()) {
-      label_button_->SetText(ASCIIToUTF16(
-          label_button_->GetText().empty()
+      label_button->SetText(ASCIIToUTF16(
+          label_button->GetText().empty()
               ? kLongText
-              : label_button_->GetText().length() > 50 ? kLabelButton : ""));
+              : label_button->GetText().length() > 50 ? kLabelButton : ""));
     } else if (event.IsAltDown()) {
-      label_button_->SetImage(Button::STATE_NORMAL,
-          label_button_->GetImage(Button::STATE_NORMAL).isNull() ?
-          *icon_ : gfx::ImageSkia());
+      label_button->SetImage(
+          Button::STATE_NORMAL,
+          label_button->GetImage(Button::STATE_NORMAL).isNull()
+              ? *icon_
+              : gfx::ImageSkia());
     } else {
       static int alignment = 0;
-      label_button_->SetHorizontalAlignment(
+      label_button->SetHorizontalAlignment(
           static_cast<gfx::HorizontalAlignment>(++alignment % 3));
     }
   } else if (event.IsShiftDown()) {
     if (event.IsAltDown()) {
-      label_button_->SetFocusable(!label_button_->IsFocusable());
+      label_button->SetFocusable(!label_button->IsFocusable());
     } else {
-      label_button_->SetStyle(static_cast<Button::ButtonStyle>(
-          (label_button_->style() + 1) % Button::STYLE_COUNT));
+      label_button->SetStyle(static_cast<Button::ButtonStyle>(
+          (label_button->style() + 1) % Button::STYLE_COUNT));
     }
   } else if (event.IsAltDown()) {
-    label_button_->SetIsDefault(!label_button_->is_default());
+    label_button->SetIsDefault(!label_button->is_default());
   } else {
-    label_button_->SetMinSize(gfx::Size());
+    label_button->SetMinSize(gfx::Size());
   }
   example_view()->GetLayoutManager()->Layout(example_view());
 }
 
 void ButtonExample::ButtonPressed(Button* sender, const ui::Event& event) {
   if (sender == label_button_)
-    LabelButtonPressed(event);
+    LabelButtonPressed(label_button_, event);
+  else if (sender == styled_button_)
+    LabelButtonPressed(styled_button_, event);
+  else if (sender == disabled_button_)
+    LabelButtonPressed(disabled_button_, event);
   else
     PrintStatus("Image Button Pressed! count: %d", ++count_);
 }
diff --git a/ui/views/examples/button_example.h b/ui/views/examples/button_example.h
index 566d3f0..956759c 100644
--- a/ui/views/examples/button_example.h
+++ b/ui/views/examples/button_example.h
@@ -27,19 +27,21 @@
   void CreateExampleView(View* container) override;
 
  private:
-  void LabelButtonPressed(const ui::Event& event);
+  void LabelButtonPressed(LabelButton* label_button, const ui::Event& event);
 
   // ButtonListener:
   void ButtonPressed(Button* sender, const ui::Event& event) override;
 
   // Example buttons.
-  LabelButton* label_button_;
-  ImageButton* image_button_;
+  LabelButton* label_button_ = nullptr;
+  LabelButton* styled_button_ = nullptr;
+  LabelButton* disabled_button_ = nullptr;
+  ImageButton* image_button_ = nullptr;
 
-  const gfx::ImageSkia* icon_;
+  const gfx::ImageSkia* icon_ = nullptr;
 
   // The number of times the buttons are pressed.
-  int count_;
+  int count_ = 0;
 
   DISALLOW_COPY_AND_ASSIGN(ButtonExample);
 };
diff --git a/ui/views/style/mac/combobox_background_mac.cc b/ui/views/style/mac/combobox_background_mac.cc
index 31997b1..805f97d2 100644
--- a/ui/views/style/mac/combobox_background_mac.cc
+++ b/ui/views/style/mac/combobox_background_mac.cc
@@ -11,6 +11,8 @@
 #include "ui/views/controls/combobox/combobox.h"
 #include "ui/views/view.h"
 
+using ui::NativeThemeMac;
+
 namespace views {
 
 ComboboxBackgroundMac::ComboboxBackgroundMac() {}
@@ -27,15 +29,17 @@
   // paint outside the border.
   bounds.Inset(bounds.width() - combobox->GetArrowButtonWidth(), 0.5, 0.5, 0.5);
 
-  ui::NativeTheme::State state = ui::NativeTheme::kNormal;
+  // TODO(tapted): Check whether the Widget is active, and use the NORMAL
+  // BackgroundType if it is inactive. Handling this properly also requires the
+  // control to observe the Widget for activation changes and invalidate.
+  NativeThemeMac::ButtonBackgroundType type =
+      NativeThemeMac::ButtonBackgroundType::HIGHLIGHTED;
   if (!combobox->enabled())
-    state = ui::NativeTheme::kDisabled;
+    type = NativeThemeMac::ButtonBackgroundType::DISABLED;
 
   SkPaint paint;
   paint.setShader(
-      ui::NativeThemeMac::GetButtonBackgroundShader(
-          state,
-          bounds.height()));
+      NativeThemeMac::GetButtonBackgroundShader(type, bounds.height()));
   paint.setStyle(SkPaint::kFill_Style);
   paint.setAntiAlias(true);
 
diff --git a/ui/views/style/mac/dialog_button_border_mac.cc b/ui/views/style/mac/dialog_button_border_mac.cc
index 366fbc2..bb22ac6 100644
--- a/ui/views/style/mac/dialog_button_border_mac.cc
+++ b/ui/views/style/mac/dialog_button_border_mac.cc
@@ -12,109 +12,56 @@
 #include "third_party/skia/include/core/SkPath.h"
 #include "third_party/skia/include/effects/SkGradientShader.h"
 #include "ui/gfx/canvas.h"
+#include "ui/native_theme/native_theme_mac.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/button/custom_button.h"
+#include "ui/views/controls/button/label_button.h"
+
+using ui::NativeThemeMac;
 
 namespace views {
 namespace {
 
-// Type to map button states to a corresponding SkColor.
-typedef const SkColor ColorByState[Button::STATE_COUNT];
-
-// If a state is added, ColorByState will silently fill with zeros, so assert.
-static_assert(Button::STATE_COUNT == 4,
-              "DialogButtonBorderMac assumes 4 button states.");
-
 // Corner radius of rounded rectangles.
 const SkScalar kCornerRadius = 2;
+const SkScalar kFocusCornerRadius = 4;
+const SkScalar kFocusRingThickness = 3;
 
-// Vertical offset of the drop shadow and the inner highlight shadow.
-const SkScalar kShadowOffsetY = 1;
-
-// Shadow blur radius of the inner highlight shadow.
-const double kInnerShadowBlurRadius = 2.0;
+const SkColor kDefaultBorderColor = SkColorSetARGB(0xF2, 0xBA, 0xBA, 0xBA);
+const SkColor kHighlightedBorderColor = SkColorSetARGB(0xFF, 0x52, 0x76, 0xFF);
+const SkColor kFocusRingColor = SkColorSetARGB(0x80, 0x3B, 0x9A, 0xFC);
 
 // Default border insets, to provide text padding.
-const int kPaddingX = 14;
-const int kPaddingY = 4;
+const int kPaddingX = 19;
+const int kPaddingY = 7;
 
-sk_sp<SkShader> CreateButtonGradient(int height,
-                                     Button::ButtonState state) {
-  ColorByState start = {0xFFF0F0F0, 0xFFF4F4F4, 0xFFEBEBEB, 0xFFEDEDED};
-  ColorByState end = {0xFFE0E0E0, 0xFFE4E4E4, 0xFFDBDBDB, 0xFFDEDEDE};
-
-  SkPoint gradient_points[2];
-  gradient_points[0].iset(0, 0);
-  gradient_points[1].iset(0, height);
-
-  SkColor gradient_colors[] = {start[state], start[state], end[state]};
-  SkScalar gradient_positions[] = {0.0, 0.38, 1.0};
-
-  return SkGradientShader::MakeLinear(
-          gradient_points, gradient_colors, gradient_positions, 3,
-          SkShader::kClamp_TileMode);
-}
-
-void DrawConstrainedButtonBackground(const SkRect& button_rect,
-                                     SkCanvas* canvas,
-                                     Button::ButtonState button_state) {
+void DrawDialogButtonBackground(const SkRect& button_rect,
+                                SkCanvas* canvas,
+                                const LabelButton& button) {
   // Extend the size of the SkRect so the border stroke is drawn over it on all
   // sides.
   SkRect rect(button_rect);
   rect.fRight += 1;
   rect.fBottom += 1;
 
-  SkPaint paint;
-
-  // Drop Shadow.
-  ColorByState shadow = {0x14000000, 0x1F000000, 0x00000000, 0x00000000};
-  const double blur = 0.0;
-  std::vector<gfx::ShadowValue> shadows(
-      1, gfx::ShadowValue(gfx::Vector2d(0, kShadowOffsetY), blur,
-                          shadow[button_state]));
-  paint.setLooper(gfx::CreateShadowDrawLooper(shadows));
+  NativeThemeMac::ButtonBackgroundType type =
+      NativeThemeMac::ButtonBackgroundType::NORMAL;
+  if (!button.enabled() || button.state() == Button::STATE_DISABLED)
+    type = NativeThemeMac::ButtonBackgroundType::DISABLED;
+  else if (button.state() == Button::STATE_PRESSED)
+    type = NativeThemeMac::ButtonBackgroundType::PRESSED;
+  else if (DialogButtonBorderMac::ShouldRenderDefault(button))
+    type = NativeThemeMac::ButtonBackgroundType::HIGHLIGHTED;
 
   // Background.
-  paint.setShader(CreateButtonGradient(rect.height(), button_state));
+  SkPaint paint;
+  paint.setShader(
+      NativeThemeMac::GetButtonBackgroundShader(type, rect.height()));
   paint.setStyle(SkPaint::kFill_Style);
   paint.setFlags(SkPaint::kAntiAlias_Flag);
   canvas->drawRoundRect(rect, kCornerRadius, kCornerRadius, paint);
 }
 
-// Draws an inner box shadow inside a rounded rectangle of size |rect|. The
-// technique: draw a black "ring" around the outside of the button cell. Then
-// clip out everything except the shadow it casts. Works similar to Blink's
-// GraphicsContext::drawInnerShadow().
-void DrawRoundRectInnerShadow(const SkRect& rect,
-                              SkCanvas* canvas,
-                              SkColor shadow_color) {
-  const gfx::Vector2d shadow_offset(0, kShadowOffsetY);
-  SkRect outer(rect);
-  outer.outset(abs(shadow_offset.x()) + kInnerShadowBlurRadius,
-               abs(shadow_offset.y()) + kInnerShadowBlurRadius);
-
-  SkPath path;
-  path.addRect(outer);
-  path.setFillType(SkPath::kEvenOdd_FillType);
-  path.addRoundRect(rect, kCornerRadius, kCornerRadius);  // Poke a hole.
-
-  // Inset the clip to cater for the border stroke.
-  SkPath clip;
-  clip.addRoundRect(rect.makeInset(0.5, 0.5), kCornerRadius, kCornerRadius);
-
-  SkPaint paint;
-  std::vector<gfx::ShadowValue> shadows(
-      1, gfx::ShadowValue(shadow_offset, kInnerShadowBlurRadius, shadow_color));
-  paint.setLooper(gfx::CreateShadowDrawLooper(shadows));
-  paint.setStyle(SkPaint::kFill_Style);
-  paint.setColor(SK_ColorBLACK);  // Note: Entirely clipped.
-
-  canvas->save();
-  canvas->clipPath(clip, SkRegion::kIntersect_Op, true /* antialias */);
-  canvas->drawPath(path, paint);
-  canvas->restore();
-}
-
 }  // namespace
 
 DialogButtonBorderMac::DialogButtonBorderMac() {
@@ -123,39 +70,54 @@
 
 DialogButtonBorderMac::~DialogButtonBorderMac() {}
 
+// static
+bool DialogButtonBorderMac::ShouldRenderDefault(const LabelButton& button) {
+  // TODO(tapted): Check whether the Widget is active, and only return true here
+  // if it is. Plumbing this requires default buttons to also observe Widget
+  // activations to ensure text and background colors are properly invalidated.
+  return button.is_default();
+}
+
 void DialogButtonBorderMac::Paint(const View& view, gfx::Canvas* canvas) {
+  // Actually, |view| should be a LabelButton as well, but don't rely too much
+  // on RTTI.
   DCHECK(CustomButton::AsCustomButton(&view));
-  const CustomButton& button = static_cast<const CustomButton&>(view);
+  const LabelButton& button = static_cast<const LabelButton&>(view);
   SkCanvas* canvas_skia = canvas->sk_canvas();
 
   // Inset all sides for the rounded rectangle stroke. Inset again to make room
-  // for the shadows (while keeping the text centered).
+  // for the shadows and static focus ring (while keeping the text centered).
   SkRect sk_rect = gfx::RectToSkRect(view.GetLocalBounds());
-  sk_rect.inset(2.0, 2.0);
+  sk_rect.inset(kFocusRingThickness, kFocusRingThickness);
 
-  DrawConstrainedButtonBackground(sk_rect, canvas_skia, button.state());
+  DrawDialogButtonBackground(sk_rect, canvas_skia, button);
 
   // Offset so that strokes are contained within the pixel boundary.
   sk_rect.offset(0.5, 0.5);
-  ColorByState highlight = {0xBFFFFFFF, 0xF2FFFFFF, 0x24000000, 0x00000000};
-  DrawRoundRectInnerShadow(sk_rect, canvas_skia, highlight[button.state()]);
 
-  // Border or focus ring.
+  // Border and focus ring.
+  SkColor border_color = kDefaultBorderColor;
+  if (button.state() == Button::STATE_PRESSED || ShouldRenderDefault(button))
+    border_color = kHighlightedBorderColor;
+
   SkPaint paint;
-  ColorByState border = {0x40000000, 0x4D000000, 0x4D000000, 0x1F000000};
-  const SkColor focus_border = {0xFF5DA5FF};
-  paint.setStrokeWidth(1);
   paint.setStyle(SkPaint::kStroke_Style);
   paint.setFlags(SkPaint::kAntiAlias_Flag);
-  if (button.HasFocus() && button.state() != Button::STATE_PRESSED)
-    paint.setColor(focus_border);
-  else
-    paint.setColor(border[button.state()]);
+  paint.setStrokeWidth(1);
+  paint.setColor(border_color);
   canvas_skia->drawRoundRect(sk_rect, kCornerRadius, kCornerRadius, paint);
+
+  if (button.HasFocus()) {
+    paint.setStrokeWidth(kFocusRingThickness);
+    paint.setColor(kFocusRingColor);
+    sk_rect.inset(-1, -1);
+    canvas_skia->drawRoundRect(sk_rect, kFocusCornerRadius, kFocusCornerRadius,
+                               paint);
+  }
 }
 
 gfx::Size DialogButtonBorderMac::GetMinimumSize() const {
-  return gfx::Size(100, 30);
+  return gfx::Size(28, 4);
 }
 
 }  // namespace views
diff --git a/ui/views/style/mac/dialog_button_border_mac.h b/ui/views/style/mac/dialog_button_border_mac.h
index a45bc48..b10b09a 100644
--- a/ui/views/style/mac/dialog_button_border_mac.h
+++ b/ui/views/style/mac/dialog_button_border_mac.h
@@ -11,6 +11,8 @@
 
 namespace views {
 
+class LabelButton;
+
 // Skia port of the default button style used for dialogs on Chrome Mac.
 // Originally provided by ConstrainedWindowButton, which used Quartz-backed
 // Cocoa drawing routines.
@@ -19,6 +21,9 @@
   DialogButtonBorderMac();
   ~DialogButtonBorderMac() override;
 
+  // Whether the given |button| should get a highlighted background.
+  static bool ShouldRenderDefault(const LabelButton& button);
+
   // views::Border:
   void Paint(const View& view, gfx::Canvas* canvas) override;
   gfx::Size GetMinimumSize() const override;
diff --git a/ui/views/style/platform_style.cc b/ui/views/style/platform_style.cc
index 6719c9b..84847674 100644
--- a/ui/views/style/platform_style.cc
+++ b/ui/views/style/platform_style.cc
@@ -7,6 +7,8 @@
 #include "build/build_config.h"
 #include "ui/base/material_design/material_design_controller.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/shadow_value.h"
+#include "ui/native_theme/native_theme.h"
 #include "ui/resources/grit/ui_resources.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/button/label_button.h"
@@ -14,10 +16,27 @@
 #include "ui/views/controls/focusable_border.h"
 #include "ui/views/controls/scrollbar/native_scroll_bar.h"
 
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#define DESKTOP_LINUX
+#endif
+
 namespace views {
+namespace {
+
+#if !defined(DESKTOP_LINUX) && !defined(OS_MACOSX)
+// Default text and shadow colors for STYLE_BUTTON.
+const SkColor kStyleButtonTextColor = SK_ColorBLACK;
+const SkColor kStyleButtonShadowColor = SK_ColorWHITE;
+#endif
+
+}  // namespace
 
 #if !defined(OS_MACOSX)
 
+const int PlatformStyle::kMinLabelButtonWidth = 70;
+const int PlatformStyle::kMinLabelButtonHeight = 33;
+const bool PlatformStyle::kDefaultLabelButtonHasBoldFont = true;
+
 // static
 gfx::ImageSkia PlatformStyle::CreateComboboxArrow(bool is_enabled,
                                                   Combobox::Style style) {
@@ -53,9 +72,36 @@
 scoped_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) {
   return make_scoped_ptr(new NativeScrollBar(is_horizontal));
 }
+
+// static
+SkColor PlatformStyle::TextColorForButton(
+    const ButtonColorByState& color_by_state,
+    const LabelButton& button) {
+  return color_by_state[button.state()];
+}
+
+#endif  // OS_MACOSX
+
+#if !defined(DESKTOP_LINUX) && !defined(OS_MACOSX)
+// static
+void PlatformStyle::ApplyLabelButtonTextStyle(
+    Label* label,
+    ButtonColorByState* color_by_state) {
+  ButtonColorByState& colors = *color_by_state;
+  colors[Button::STATE_NORMAL] = kStyleButtonTextColor;
+  colors[Button::STATE_HOVERED] = kStyleButtonTextColor;
+  colors[Button::STATE_PRESSED] = kStyleButtonTextColor;
+
+  const ui::NativeTheme* theme = label->GetNativeTheme();
+  label->SetBackgroundColor(
+      theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonBackgroundColor));
+  label->SetAutoColorReadabilityEnabled(false);
+  label->SetShadows(gfx::ShadowValues(
+      1, gfx::ShadowValue(gfx::Vector2d(0, 1), 0, kStyleButtonShadowColor)));
+}
 #endif
 
-#if !defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if !defined(DESKTOP_LINUX)
 // static
 scoped_ptr<Border> PlatformStyle::CreateThemedLabelButtonBorder(
     LabelButton* button) {
diff --git a/ui/views/style/platform_style.h b/ui/views/style/platform_style.h
index 3103691..36bc1fc 100644
--- a/ui/views/style/platform_style.h
+++ b/ui/views/style/platform_style.h
@@ -9,18 +9,30 @@
 #include "base/memory/scoped_ptr.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/combobox/combobox.h"
+#include "ui/views/views_export.h"
 
 namespace views {
 
 class Border;
 class FocusableBorder;
+class Label;
 class LabelButton;
 class LabelButtonBorder;
 class ScrollBar;
 
 // Cross-platform API for providing platform-specific styling for toolkit-views.
-class PlatformStyle {
+class VIEWS_EXPORT PlatformStyle {
  public:
+  // Type used by LabelButton to map button states to text colors.
+  using ButtonColorByState = SkColor[Button::STATE_COUNT];
+
+  // Minimum size for platform-styled buttons (Button::STYLE_BUTTON).
+  static const int kMinLabelButtonWidth;
+  static const int kMinLabelButtonHeight;
+
+  // Whether dialog-default buttons are given a bold font style.
+  static const bool kDefaultLabelButtonHasBoldFont;
+
   // Creates an ImageSkia containing the image to use for the combobox arrow.
   // The |is_enabled| argument is true if the control the arrow is for is
   // enabled, and false if the control is disabled. The |style| argument is the
@@ -39,12 +51,22 @@
   static scoped_ptr<LabelButtonBorder> CreateLabelButtonBorder(
       Button::ButtonStyle style);
 
-  // Applies the current system theme to the default border created by |button|.
-  static scoped_ptr<Border> CreateThemedLabelButtonBorder(LabelButton* button);
-
   // Creates the default scrollbar for the given orientation.
   static scoped_ptr<ScrollBar> CreateScrollBar(bool is_horizontal);
 
+  // Returns the current text color for the current button state.
+  static SkColor TextColorForButton(const ButtonColorByState& color_by_state,
+                                    const LabelButton& button);
+
+  // Applies platform styles to |label| and fills |color_by_state| with the text
+  // colors for normal, pressed, hovered, and disabled states, if the colors for
+  // Button::STYLE_BUTTON buttons differ from those provided by ui::NativeTheme.
+  static void ApplyLabelButtonTextStyle(Label* label,
+                                        ButtonColorByState* color_by_state);
+
+  // Applies the current system theme to the default border created by |button|.
+  static scoped_ptr<Border> CreateThemedLabelButtonBorder(LabelButton* button);
+
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformStyle);
 };
diff --git a/ui/views/style/platform_style_linux.cc b/ui/views/style/platform_style_linux.cc
index 36e3de58..829d96d 100644
--- a/ui/views/style/platform_style_linux.cc
+++ b/ui/views/style/platform_style_linux.cc
@@ -19,4 +19,12 @@
   return button->CreateDefaultBorder();
 }
 
+void PlatformStyle::ApplyLabelButtonTextStyle(Label* label,
+                                              ButtonColorByState* colors) {
+  // TODO(erg): This is disabled on desktop linux because of the binary asset
+  // confusion. These details should either be pushed into ui::NativeThemeWin
+  // or should be obsoleted by rendering buttons with paint calls instead of
+  // with static assets. http://crbug.com/350498
+}
+
 }  // namespace views
diff --git a/ui/views/style/platform_style_mac.mm b/ui/views/style/platform_style_mac.mm
index cbe9be5..b2170ca1 100644
--- a/ui/views/style/platform_style_mac.mm
+++ b/ui/views/style/platform_style_mac.mm
@@ -17,6 +17,10 @@
 
 namespace views {
 
+const int PlatformStyle::kMinLabelButtonWidth = 32;
+const int PlatformStyle::kMinLabelButtonHeight = 30;
+const bool PlatformStyle::kDefaultLabelButtonHasBoldFont = false;
+
 // static
 gfx::ImageSkia PlatformStyle::CreateComboboxArrow(bool is_enabled,
                                                   Combobox::Style style) {
@@ -56,4 +60,28 @@
   return make_scoped_ptr(new CocoaScrollBar(is_horizontal));
 }
 
+// static
+SkColor PlatformStyle::TextColorForButton(
+    const ButtonColorByState& color_by_state,
+    const LabelButton& button) {
+  Button::ButtonState state = button.state();
+  if (button.style() == Button::STYLE_BUTTON &&
+      DialogButtonBorderMac::ShouldRenderDefault(button)) {
+    // For convenience, we currently assume Mac wants the color corresponding to
+    // the pressed state for default buttons.
+    state = Button::STATE_PRESSED;
+  }
+  return color_by_state[state];
+}
+
+// static
+void PlatformStyle::ApplyLabelButtonTextStyle(
+    views::Label* label,
+    ButtonColorByState* color_by_state) {
+  const ui::NativeTheme* theme = label->GetNativeTheme();
+  ButtonColorByState& colors = *color_by_state;
+  colors[Button::STATE_PRESSED] =
+      theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor);
+}
+
 }  // namespace views
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc
index 62a800c..5b65adb 100644
--- a/ui/views/window/dialog_client_view.cc
+++ b/ui/views/window/dialog_client_view.cc
@@ -112,6 +112,8 @@
     delete cancel_button_;
     cancel_button_ = NULL;
   }
+
+  SetupFocusChain();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -233,8 +235,6 @@
     else if (details.child == extra_view_)
       extra_view_ = nullptr;
   }
-
-  SetupFocusChain();
 }
 
 void DialogClientView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
@@ -286,6 +286,7 @@
   if (extra_view_) {
     extra_view_->SetGroup(kButtonGroup);
     AddChildView(extra_view_);
+    SetupFocusChain();
   }
 }
 
@@ -352,11 +353,10 @@
       std::remove(child_views.begin(), child_views.end(), nullptr),
       child_views.end());
 
-  // Setup focus.
-  for (size_t i = 0; i < child_views.size(); i++) {
-    child_views[i]->SetNextFocusableView(
-        i + 1 != child_views.size() ? child_views[i + 1] : nullptr);
-  }
+  // Setup focus by reordering views. It is not safe to use SetNextFocusableView
+  // since child views may be added externally to this view.
+  for (size_t i = 0; i < child_views.size(); i++)
+    ReorderChildView(child_views[i], i);
 }
 
 }  // namespace views
diff --git a/ui/views/window/dialog_client_view_unittest.cc b/ui/views/window/dialog_client_view_unittest.cc
index f4f72eef..9078aba 100644
--- a/ui/views/window/dialog_client_view_unittest.cc
+++ b/ui/views/window/dialog_client_view_unittest.cc
@@ -17,14 +17,15 @@
 
 class TestDialogClientView : public DialogClientView {
  public:
-  TestDialogClientView(View* contents_view,
-                       DialogDelegate* dialog_delegate)
-      : DialogClientView(contents_view),
-        dialog_(dialog_delegate) {}
+  explicit TestDialogClientView(DialogDelegateView* dialog_delegate_view)
+      : DialogClientView(dialog_delegate_view),
+        dialog_delegate_view_(dialog_delegate_view) {}
   ~TestDialogClientView() override {}
 
   // DialogClientView implementation.
-  DialogDelegate* GetDialogDelegate() const override { return dialog_; }
+  DialogDelegate* GetDialogDelegate() const override {
+    return dialog_delegate_view_;
+  }
 
   View* GetContentsView() { return contents_view(); }
 
@@ -33,11 +34,13 @@
   }
 
  private:
-  DialogDelegate* dialog_;
+  DialogDelegateView* dialog_delegate_view_;
 
   DISALLOW_COPY_AND_ASSIGN(TestDialogClientView);
 };
 
+// Base class for tests. Also acts as the dialog delegate and contents view for
+// TestDialogClientView.
 class DialogClientViewTest : public ViewsTestBase,
                              public DialogDelegateView {
  public:
@@ -49,14 +52,14 @@
   // testing::Test implementation.
   void SetUp() override {
     dialog_buttons_ = ui::DIALOG_BUTTON_NONE;
-    contents_.reset(new StaticSizedView(gfx::Size(100, 200)));
-    client_view_.reset(new TestDialogClientView(contents_.get(), this));
-
+    client_view_.reset(new TestDialogClientView(this));
+    // Add this i.e. the contents view as a child of |client_view_|. This is
+    // generally done when the client view is added to the view hierarchy.
+    client_view_->AddChildViewAt(this, 0);
     ViewsTestBase::SetUp();
   }
 
   // DialogDelegateView implementation.
-  View* GetContentsView() override { return contents_.get(); }
   View* CreateExtraView() override { return extra_view_; }
   bool GetExtraViewPadding(int* padding) override {
     if (extra_view_padding_)
@@ -76,11 +79,11 @@
   // the requested amount, but height should always match exactly.
   void CheckContentsIsSetToPreferredSize() {
     const gfx::Rect client_bounds = GetUpdatedClientBounds();
-    const gfx::Size preferred_size = contents_->GetPreferredSize();
-    EXPECT_EQ(preferred_size.height(), contents_->bounds().height());
-    EXPECT_LE(preferred_size.width(), contents_->bounds().width());
-    EXPECT_EQ(contents_->bounds().origin(), client_bounds.origin());
-    EXPECT_EQ(contents_->bounds().right(), client_bounds.right());
+    const gfx::Size preferred_size = this->GetPreferredSize();
+    EXPECT_EQ(preferred_size.height(), this->bounds().height());
+    EXPECT_LE(preferred_size.width(), this->bounds().width());
+    EXPECT_EQ(this->bounds().origin(), client_bounds.origin());
+    EXPECT_EQ(this->bounds().right(), client_bounds.right());
   }
 
   // Sets the buttons to show in the dialog and refreshes the dialog.
@@ -106,8 +109,6 @@
   TestDialogClientView* client_view() { return client_view_.get(); }
 
  private:
-  // The contents of the dialog.
-  scoped_ptr<View> contents_;
   // The DialogClientView that's being tested.
   scoped_ptr<TestDialogClientView> client_view_;
   // The bitmask of buttons to show in the dialog.
@@ -202,6 +203,11 @@
             client_view()->GetContentsView()->GetNextFocusableView());
   EXPECT_EQ(client_view()->cancel_button(), extra_view->GetNextFocusableView());
   EXPECT_EQ(nullptr, client_view()->cancel_button()->GetNextFocusableView());
+
+  // Add a dummy view to the client view.
+  View* dummy_view = new StaticSizedView(gfx::Size(200, 200));
+  client_view()->AddChildView(dummy_view);
+  EXPECT_EQ(dummy_view, client_view()->cancel_button()->GetNextFocusableView());
 }
 
 // Test that the contents view gets its preferred size in the basic dialog