Update Chromium files

Revision: 2b39aaf5dc7d0b0e00ce680b553f369753c0aa7e
diff --git a/AUTHORS b/AUTHORS
index 14b2e43..4810a10 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -421,6 +421,7 @@
 Qing Zhang <qing.zhang@intel.com>
 Qi Yang <qi1988.yang@samsung.com>
 Radu Stavila <stavila@adobe.com>
+Radu Velea <radu.velea@intel.com>
 Rafael Antognolli <rafael.antognolli@intel.com>
 Raghavendra Ghatage <r.ghatage@samsung.com>
 Rahul Gupta <rahul.g@samsung.com>
diff --git a/base/BUILD.gn b/base/BUILD.gn
index f4eb27f..de282cf 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -167,8 +167,8 @@
     "callback_internal.cc",
     "callback_internal.h",
     "cancelable_callback.h",
-    "chromeos/memory_pressure_monitor_chromeos.cc",
-    "chromeos/memory_pressure_monitor_chromeos.h",
+    "chromeos/memory_pressure_monitor.cc",
+    "chromeos/memory_pressure_monitor.h",
     "command_line.cc",
     "command_line.h",
     "compiler_specific.h",
@@ -271,6 +271,8 @@
     "mac/bundle_locations.h",
     "mac/bundle_locations.mm",
     "mac/cocoa_protocols.h",
+    "mac/dispatch_source_mach.cc",
+    "mac/dispatch_source_mach.h",
     "mac/foundation_util.h",
     "mac/foundation_util.mm",
     "mac/launch_services_util.cc",
@@ -285,8 +287,8 @@
     "mac/mac_util.mm",
     "mac/mach_logging.cc",
     "mac/mach_logging.h",
-    "mac/memory_pressure_monitor_mac.cc",
-    "mac/memory_pressure_monitor_mac.h",
+    "mac/memory_pressure_monitor.cc",
+    "mac/memory_pressure_monitor.h",
     "mac/objc_property_releaser.h",
     "mac/objc_property_releaser.mm",
     "mac/os_crash_dumps.cc",
@@ -1096,7 +1098,7 @@
     "callback_unittest.cc",
     "callback_unittest.nc",
     "cancelable_callback_unittest.cc",
-    "chromeos/memory_pressure_monitor_chromeos_unittest.cc",
+    "chromeos/memory_pressure_monitor_unittest.cc",
     "command_line_unittest.cc",
     "containers/adapters_unittest.cc",
     "containers/hash_tables_unittest.cc",
@@ -1150,6 +1152,7 @@
     "lazy_instance_unittest.cc",
     "logging_unittest.cc",
     "mac/bind_objc_block_unittest.mm",
+    "mac/dispatch_source_mach_unittest.cc",
     "mac/foundation_util_unittest.mm",
     "mac/libdispatch_task_runner_unittest.cc",
     "mac/mac_util_unittest.mm",
diff --git a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java
index 2946f6f..c87d02d 100644
--- a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java
+++ b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java
@@ -11,6 +11,10 @@
 import android.view.KeyEvent;
 import android.view.Window;
 
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
 /**
  * Basic application functionality that should be shared among all browser applications.
  */
@@ -30,66 +34,94 @@
     private ObserverList<WindowFocusChangedListener> mWindowFocusListeners =
             new ObserverList<WindowFocusChangedListener>();
 
+    /**
+     * Intercepts calls to an existing Window.Callback. Most invocations are passed on directly
+     * to the composed Window.Callback but enables intercepting/manipulating others.
+     *
+     * This is used to relay window focus changes throughout the app and remedy a bug in the
+     * appcompat library.
+     */
+    private class WindowCallbackProxy implements InvocationHandler {
+        private final Window.Callback mCallback;
+        private final Activity mActivity;
+
+        public WindowCallbackProxy(Activity activity, Window.Callback callback) {
+            mCallback = callback;
+            mActivity = activity;
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            if (method.getName().equals("onWindowFocusChanged") && args.length == 1
+                    && args[0] instanceof Boolean) {
+                onWindowFocusChanged((boolean) args[0]);
+                return null;
+            } else if (method.getName().equals("dispatchKeyEvent") && args.length == 1
+                    && args[0] instanceof KeyEvent) {
+                return dispatchKeyEvent((KeyEvent) args[0]);
+            } else {
+                return method.invoke(mCallback, args);
+            }
+        }
+
+        public void onWindowFocusChanged(boolean hasFocus) {
+            mCallback.onWindowFocusChanged(hasFocus);
+
+            for (WindowFocusChangedListener listener : mWindowFocusListeners) {
+                listener.onWindowFocusChanged(mActivity, hasFocus);
+            }
+        }
+
+        public boolean dispatchKeyEvent(KeyEvent event) {
+            // TODO(aurimas): remove this once AppCompatDelegateImpl no longer steals
+            // KEYCODE_MENU. (see b/20529185)
+            if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && mActivity.dispatchKeyEvent(event)) {
+                return true;
+            }
+            return mCallback.dispatchKeyEvent(event);
+        }
+    }
     @Override
     public void onCreate() {
         super.onCreate();
         ApplicationStatus.initialize(this);
-
         registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
             @Override
             public void onActivityCreated(final Activity activity, Bundle savedInstanceState) {
                 Window.Callback callback = activity.getWindow().getCallback();
-                activity.getWindow().setCallback(new WindowCallbackWrapper(callback) {
-                    @Override
-                    public void onWindowFocusChanged(boolean hasFocus) {
-                        super.onWindowFocusChanged(hasFocus);
-
-                        for (WindowFocusChangedListener listener : mWindowFocusListeners) {
-                            listener.onWindowFocusChanged(activity, hasFocus);
-                        }
-                    }
-
-                    @Override
-                    public boolean dispatchKeyEvent(KeyEvent event) {
-                        // TODO(aurimas): remove this once AppCompatDelegateImpl no longer steals
-                        // KEYCODE_MENU. (see b/20529185)
-                        if (event.getKeyCode() == KeyEvent.KEYCODE_MENU
-                                && activity.dispatchKeyEvent(event)) {
-                            return true;
-                        }
-                        return super.dispatchKeyEvent(event);
-                    }
-                });
+                activity.getWindow().setCallback((Window.Callback) Proxy.newProxyInstance(
+                        Window.Callback.class.getClassLoader(), new Class[] {Window.Callback.class},
+                        new WindowCallbackProxy(activity, callback)));
             }
 
             @Override
             public void onActivityDestroyed(Activity activity) {
-                assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+                assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
             }
 
             @Override
             public void onActivityPaused(Activity activity) {
-                assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+                assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
             }
 
             @Override
             public void onActivityResumed(Activity activity) {
-                assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+                assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
             }
 
             @Override
             public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
-                assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+                assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
             }
 
             @Override
             public void onActivityStarted(Activity activity) {
-                assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+                assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
             }
 
             @Override
             public void onActivityStopped(Activity activity) {
-                assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+                assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
             }
         });
     }
diff --git a/base/android/java/src/org/chromium/base/WindowCallbackWrapper.java b/base/android/java/src/org/chromium/base/WindowCallbackWrapper.java
deleted file mode 100644
index 0718c22..0000000
--- a/base/android/java/src/org/chromium/base/WindowCallbackWrapper.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2014 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.
-
-package org.chromium.base;
-
-import android.annotation.SuppressLint;
-import android.view.ActionMode;
-import android.view.ActionMode.Callback;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityEvent;
-
-/**
- * A wrapper for a Window.Callback instance, allowing subclasses to listen to or override specific
- * window messages.
- */
-class WindowCallbackWrapper implements Window.Callback {
-    private final Window.Callback mCallback;
-
-    public WindowCallbackWrapper(Window.Callback callback) {
-        mCallback = callback;
-    }
-
-    @Override
-    public boolean dispatchGenericMotionEvent(MotionEvent event) {
-        return mCallback.dispatchGenericMotionEvent(event);
-    }
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        return mCallback.dispatchKeyEvent(event);
-    }
-
-    @Override
-    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
-        return mCallback.dispatchKeyShortcutEvent(event);
-    }
-
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        return mCallback.dispatchPopulateAccessibilityEvent(event);
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent event) {
-        return mCallback.dispatchTouchEvent(event);
-    }
-
-    @Override
-    public boolean dispatchTrackballEvent(MotionEvent event) {
-        return mCallback.dispatchTrackballEvent(event);
-    }
-
-    @Override
-    public void onActionModeFinished(ActionMode mode) {
-        mCallback.onActionModeFinished(mode);
-    }
-
-    @Override
-    public void onActionModeStarted(ActionMode mode) {
-        mCallback.onActionModeStarted(mode);
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        mCallback.onAttachedToWindow();
-    }
-
-    @Override
-    public void onContentChanged() {
-        mCallback.onContentChanged();
-    }
-
-    @Override
-    public boolean onCreatePanelMenu(int featureId, Menu menu) {
-        return mCallback.onCreatePanelMenu(featureId, menu);
-    }
-
-    @Override
-    public View onCreatePanelView(int featureId) {
-        return mCallback.onCreatePanelView(featureId);
-    }
-
-    @Override
-    @SuppressLint("MissingSuperCall")
-    public void onDetachedFromWindow() {
-        mCallback.onDetachedFromWindow();
-    }
-
-    @Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
-        return mCallback.onMenuItemSelected(featureId, item);
-    }
-
-    @Override
-    public boolean onMenuOpened(int featureId, Menu menu) {
-        return mCallback.onMenuOpened(featureId, menu);
-    }
-
-    @Override
-    public void onPanelClosed(int featureId, Menu menu) {
-        mCallback.onPanelClosed(featureId, menu);
-    }
-
-    @Override
-    public boolean onPreparePanel(int featureId, View view, Menu menu) {
-        return mCallback.onPreparePanel(featureId, view, menu);
-    }
-
-    @Override
-    public boolean onSearchRequested() {
-        return mCallback.onSearchRequested();
-    }
-
-    @Override
-    public void onWindowAttributesChanged(LayoutParams attrs) {
-        mCallback.onWindowAttributesChanged(attrs);
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) {
-        mCallback.onWindowFocusChanged(hasFocus);
-    }
-
-    @Override
-    public ActionMode onWindowStartingActionMode(Callback callback) {
-        return mCallback.onWindowStartingActionMode(callback);
-    }
-
-    public void onWindowDismissed() {
-        // TODO(benm): implement me.
-    }
-
-}
diff --git a/base/android/java_runtime.h b/base/android/java_runtime.h
index bde4c5c..4ca889e 100644
--- a/base/android/java_runtime.h
+++ b/base/android/java_runtime.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_ANDROID_JAVA_RUNTIME_H
-#define BASE_ANDROID_JAVA_RUNTIME_H
+#ifndef BASE_ANDROID_JAVA_RUNTIME_H_
+#define BASE_ANDROID_JAVA_RUNTIME_H_
 
 #include "base/android/scoped_java_ref.h"
 #include "base/base_export.h"
@@ -25,4 +25,4 @@
 }  // namespace android
 }  // namespace base
 
-#endif  // BASE_ANDROID_JAVA_RUNTIME_H
+#endif  // BASE_ANDROID_JAVA_RUNTIME_H_
diff --git a/base/android/junit/src/org/chromium/base/BaseChromiumApplicationTest.java b/base/android/junit/src/org/chromium/base/BaseChromiumApplicationTest.java
new file mode 100644
index 0000000..d3441f7
--- /dev/null
+++ b/base/android/junit/src/org/chromium/base/BaseChromiumApplicationTest.java
@@ -0,0 +1,94 @@
+// Copyright 2015 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.
+
+package org.chromium.base;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.view.KeyEvent;
+
+import junit.framework.Assert;
+
+import org.chromium.base.BaseChromiumApplication.WindowFocusChangedListener;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowActivity;
+import org.robolectric.util.ActivityController;
+
+/** Unit tests for {@link BaseChromiumApplication}. */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, application = BaseChromiumApplication.class,
+        shadows = {BaseChromiumApplicationTest.TrackingShadowActivity.class})
+public class BaseChromiumApplicationTest {
+
+    @Implements(Activity.class)
+    public static class TrackingShadowActivity extends ShadowActivity {
+        private int mWindowFocusCalls;
+        private int mDispatchKeyEventCalls;
+        private boolean mReturnValueForKeyDispatch;
+
+        @Implementation
+        public void onWindowFocusChanged(@SuppressWarnings("unused") boolean hasFocus) {
+            mWindowFocusCalls++;
+        }
+
+        @Implementation
+        public boolean dispatchKeyEvent(@SuppressWarnings("unused") KeyEvent event) {
+            mDispatchKeyEventCalls++;
+            return mReturnValueForKeyDispatch;
+        }
+    }
+
+    @Test
+    public void testWindowsFocusChanged() throws Exception {
+        BaseChromiumApplication app = (BaseChromiumApplication) Robolectric.application;
+
+        WindowFocusChangedListener mock = mock(WindowFocusChangedListener.class);
+        app.registerWindowFocusChangedListener(mock);
+
+        ActivityController<Activity> controller =
+                Robolectric.buildActivity(Activity.class).create().start().visible();
+        TrackingShadowActivity shadow =
+                (TrackingShadowActivity) Robolectric.shadowOf(controller.get());
+
+        controller.get().getWindow().getCallback().onWindowFocusChanged(true);
+        // Assert that listeners were notified.
+        verify(mock).onWindowFocusChanged(controller.get(), true);
+        // Also ensure that the original activity is forwarded the notification.
+        Assert.assertEquals(1, shadow.mWindowFocusCalls);
+    }
+
+    @Test
+    public void testDispatchKeyEvent() throws Exception {
+        ActivityController<Activity> controller =
+                Robolectric.buildActivity(Activity.class).create().start().visible();
+        TrackingShadowActivity shadow =
+                (TrackingShadowActivity) Robolectric.shadowOf(controller.get());
+
+        final KeyEvent menuKey = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU);
+
+        // Ensure that key events are forwarded.
+        Assert.assertFalse(controller.get().getWindow().getCallback().dispatchKeyEvent(menuKey));
+        // This gets called twice - once to see if the activity is swallowing it, and again to
+        // dispatch it.
+        Assert.assertEquals(2, shadow.mDispatchKeyEventCalls);
+
+        // Ensure that our activity can swallow the event.
+        shadow.mReturnValueForKeyDispatch = true;
+        Assert.assertTrue(controller.get().getWindow().getCallback().dispatchKeyEvent(menuKey));
+        Assert.assertEquals(3, shadow.mDispatchKeyEventCalls);
+
+        // A non-enter key only dispatches once.
+        Assert.assertTrue(controller.get().getWindow().getCallback().dispatchKeyEvent(
+                new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SPACE)));
+        Assert.assertEquals(4, shadow.mDispatchKeyEventCalls);
+    }
+}
diff --git a/base/android/scoped_java_ref.h b/base/android/scoped_java_ref.h
index 7863c0b..8047ee8 100644
--- a/base/android/scoped_java_ref.h
+++ b/base/android/scoped_java_ref.h
@@ -178,6 +178,8 @@
     this->Reset(other);
   }
 
+  ScopedJavaGlobalRef(JNIEnv* env, T obj) { this->Reset(env, obj); }
+
   template<typename U>
   explicit ScopedJavaGlobalRef(const U& other) {
     this->Reset(other);
diff --git a/base/base.gyp b/base/base.gyp
index 1078434..ff6ce00 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -458,7 +458,7 @@
         'callback_unittest.cc',
         'callback_unittest.nc',
         'cancelable_callback_unittest.cc',
-        'chromeos/memory_pressure_monitor_chromeos_unittest.cc',
+        'chromeos/memory_pressure_monitor_unittest.cc',
         'command_line_unittest.cc',
         'containers/adapters_unittest.cc',
         'containers/hash_tables_unittest.cc',
@@ -514,10 +514,11 @@
         'lazy_instance_unittest.cc',
         'logging_unittest.cc',
         'mac/bind_objc_block_unittest.mm',
+        'mac/dispatch_source_mach_unittest.cc',
         'mac/foundation_util_unittest.mm',
         'mac/libdispatch_task_runner_unittest.cc',
         'mac/mac_util_unittest.mm',
-        'mac/memory_pressure_monitor_mac_unittest.cc',
+        'mac/memory_pressure_monitor_unittest.cc',
         'mac/objc_property_releaser_unittest.mm',
         'mac/scoped_nsobject_unittest.mm',
         'mac/scoped_objc_class_swizzler_unittest.mm',
diff --git a/base/base.gypi b/base/base.gypi
index d1ab7b3..82d810e 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -128,8 +128,8 @@
           'callback_internal.h',
           'callback_list.h',
           'cancelable_callback.h',
-          'chromeos/memory_pressure_monitor_chromeos.cc',
-          'chromeos/memory_pressure_monitor_chromeos.h',
+          'chromeos/memory_pressure_monitor.cc',
+          'chromeos/memory_pressure_monitor.h',
           'command_line.cc',
           'command_line.h',
           'compiler_specific.h',
@@ -280,6 +280,8 @@
           'mac/bundle_locations.mm',
           'mac/close_nocancel.cc',
           'mac/cocoa_protocols.h',
+          'mac/dispatch_source_mach.cc',
+          'mac/dispatch_source_mach.h',
           'mac/foundation_util.h',
           'mac/foundation_util.mm',
           'mac/launch_services_util.cc',
@@ -294,8 +296,8 @@
           'mac/mac_util.mm',
           'mac/mach_logging.cc',
           'mac/mach_logging.h',
-          'mac/memory_pressure_monitor_mac.cc',
-          'mac/memory_pressure_monitor_mac.h',
+          'mac/memory_pressure_monitor.cc',
+          'mac/memory_pressure_monitor.h',
           'mac/objc_property_releaser.h',
           'mac/objc_property_releaser.mm',
           'mac/os_crash_dumps.cc',
diff --git a/base/base64.h b/base/base64.h
index def9b67..dd72c39 100644
--- a/base/base64.h
+++ b/base/base64.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_BASE64_H__
-#define BASE_BASE64_H__
+#ifndef BASE_BASE64_H_
+#define BASE_BASE64_H_
 
 #include <string>
 
@@ -22,4 +22,4 @@
 
 }  // namespace base
 
-#endif  // BASE_BASE64_H__
+#endif  // BASE_BASE64_H_
diff --git a/base/base_paths_win.h b/base/base_paths_win.h
index 4ab6af1..9ac9e45 100644
--- a/base/base_paths_win.h
+++ b/base/base_paths_win.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_BASE_PATHS_WIN_H__
-#define BASE_BASE_PATHS_WIN_H__
+#ifndef BASE_BASE_PATHS_WIN_H_
+#define BASE_BASE_PATHS_WIN_H_
 
 // This file declares windows-specific path keys for the base module.
 // These can be used with the PathService to access various special
@@ -51,4 +51,4 @@
 
 }  // namespace base
 
-#endif  // BASE_BASE_PATHS_WIN_H__
+#endif  // BASE_BASE_PATHS_WIN_H_
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 5fc1459..e053218 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -364,9 +364,10 @@
 struct BindState;
 
 template <typename Runnable,
-          typename R, typename... Args,
+          typename R,
+          typename... Args,
           typename... BoundArgs>
-struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>>
+struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>> final
     : public BindStateBase {
  private:
   using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>;
@@ -398,14 +399,21 @@
   using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
 
   BindState(const Runnable& runnable, const BoundArgs&... bound_args)
-      : runnable_(runnable), ref_(bound_args...), bound_args_(bound_args...) {}
+      : BindStateBase(&Destroy),
+        runnable_(runnable),
+        ref_(bound_args...),
+        bound_args_(bound_args...) {}
 
   RunnableType runnable_;
   MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_;
   Tuple<BoundArgs...> bound_args_;
 
  private:
-  ~BindState() override {}
+  ~BindState() {}
+
+  static void Destroy(BindStateBase* self) {
+    delete static_cast<BindState*>(self);
+  }
 };
 
 }  // namespace internal
diff --git a/base/callback_internal.cc b/base/callback_internal.cc
index f360388..2553fe7 100644
--- a/base/callback_internal.cc
+++ b/base/callback_internal.cc
@@ -9,6 +9,15 @@
 namespace base {
 namespace internal {
 
+void BindStateBase::AddRef() {
+  AtomicRefCountInc(&ref_count_);
+}
+
+void BindStateBase::Release() {
+  if (!AtomicRefCountDec(&ref_count_))
+    destructor_(this);
+}
+
 CallbackBase::CallbackBase(const CallbackBase& c) = default;
 CallbackBase& CallbackBase::operator=(const CallbackBase& c) = default;
 
@@ -27,7 +36,7 @@
 CallbackBase::CallbackBase(BindStateBase* bind_state)
     : bind_state_(bind_state),
       polymorphic_invoke_(NULL) {
-  DCHECK(!bind_state_.get() || bind_state_->HasOneRef());
+  DCHECK(!bind_state_.get() || bind_state_->ref_count_ == 1);
 }
 
 CallbackBase::~CallbackBase() {
diff --git a/base/callback_internal.h b/base/callback_internal.h
index 8a5c437..fefd7a2 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -10,15 +10,19 @@
 
 #include <stddef.h>
 
+#include "base/atomic_ref_count.h"
 #include "base/base_export.h"
+#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/template_util.h"
 
 template <typename T>
 class ScopedVector;
 
 namespace base {
 namespace internal {
+class CallbackBase;
 
 // BindStateBase is used to provide an opaque handle that the Callback
 // class can use to represent a function object with bound arguments.  It
@@ -26,10 +30,30 @@
 // DoInvoke function to perform the function execution.  This allows
 // us to shield the Callback class from the types of the bound argument via
 // "type erasure."
-class BindStateBase : public RefCountedThreadSafe<BindStateBase> {
+// At the base level, the only task is to add reference counting data. Don't use
+// RefCountedThreadSafe since it requires the destructor to be a virtual method.
+// Creating a vtable for every BindState template instantiation results in a lot
+// of bloat. Its only task is to call the destructor which can be done with a
+// function pointer.
+class BindStateBase {
  protected:
-  friend class RefCountedThreadSafe<BindStateBase>;
-  virtual ~BindStateBase() {}
+  explicit BindStateBase(void (*destructor)(BindStateBase*))
+      : ref_count_(0), destructor_(destructor) {}
+  ~BindStateBase() = default;
+
+ private:
+  friend class scoped_refptr<BindStateBase>;
+  friend class CallbackBase;
+
+  void AddRef();
+  void Release();
+
+  AtomicRefCount ref_count_;
+
+  // Pointer to a function that will properly destroy |this|.
+  void (*destructor_)(BindStateBase*);
+
+  DISALLOW_COPY_AND_ASSIGN(BindStateBase);
 };
 
 // Holds the Callback methods that don't require specialization to reduce
diff --git a/base/callback_unittest.cc b/base/callback_unittest.cc
index 5644b85..2844aa9 100644
--- a/base/callback_unittest.cc
+++ b/base/callback_unittest.cc
@@ -35,9 +35,13 @@
 struct BindState<void(void), void(void), void(FakeInvoker)>
     : public BindStateBase {
  public:
+  BindState() : BindStateBase(&Destroy) {}
   typedef FakeInvoker InvokerType;
  private:
-  ~BindState() override {}
+  ~BindState() {}
+  static void Destroy(BindStateBase* self) {
+    delete static_cast<BindState*>(self);
+  }
 };
 
 template <>
@@ -45,9 +49,13 @@
                            void(FakeInvoker, FakeInvoker)>
     : public BindStateBase {
  public:
+  BindState() : BindStateBase(&Destroy) {}
   typedef FakeInvoker InvokerType;
  private:
-  ~BindState() override {}
+  ~BindState() {}
+  static void Destroy(BindStateBase* self) {
+    delete static_cast<BindState*>(self);
+  }
 };
 }  // namespace internal
 
diff --git a/base/chromeos/memory_pressure_monitor_chromeos.cc b/base/chromeos/memory_pressure_monitor.cc
similarity index 88%
rename from base/chromeos/memory_pressure_monitor_chromeos.cc
rename to base/chromeos/memory_pressure_monitor.cc
index 82bc6a1..5e8aadf 100644
--- a/base/chromeos/memory_pressure_monitor_chromeos.cc
+++ b/base/chromeos/memory_pressure_monitor.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/chromeos/memory_pressure_monitor_chromeos.h"
+#include "base/chromeos/memory_pressure_monitor.h"
 
 #include <fcntl.h>
 #include <sys/select.h>
@@ -15,6 +15,7 @@
 #include "base/time/time.h"
 
 namespace base {
+namespace chromeos {
 
 namespace {
 
@@ -53,10 +54,10 @@
 // Converts a |MemoryPressureThreshold| value into a used memory percentage for
 // the moderate pressure event.
 int GetModerateMemoryThresholdInPercent(
-    MemoryPressureMonitorChromeOS::MemoryPressureThresholds thresholds) {
-  return thresholds == MemoryPressureMonitorChromeOS::
+    MemoryPressureMonitor::MemoryPressureThresholds thresholds) {
+  return thresholds == MemoryPressureMonitor::
                            THRESHOLD_AGGRESSIVE_CACHE_DISCARD ||
-         thresholds == MemoryPressureMonitorChromeOS::THRESHOLD_AGGRESSIVE
+         thresholds == MemoryPressureMonitor::THRESHOLD_AGGRESSIVE
              ? kAggressiveMemoryPressureModerateThresholdPercent
              : kNormalMemoryPressureModerateThresholdPercent;
 }
@@ -64,10 +65,10 @@
 // Converts a |MemoryPressureThreshold| value into a used memory percentage for
 // the critical pressure event.
 int GetCriticalMemoryThresholdInPercent(
-    MemoryPressureMonitorChromeOS::MemoryPressureThresholds thresholds) {
-  return thresholds == MemoryPressureMonitorChromeOS::
+    MemoryPressureMonitor::MemoryPressureThresholds thresholds) {
+  return thresholds == MemoryPressureMonitor::
                            THRESHOLD_AGGRESSIVE_TAB_DISCARD ||
-         thresholds == MemoryPressureMonitorChromeOS::THRESHOLD_AGGRESSIVE
+         thresholds == MemoryPressureMonitor::THRESHOLD_AGGRESSIVE
              ? kAggressiveMemoryPressureCriticalThresholdPercent
              : kNormalMemoryPressureCriticalThresholdPercent;
 }
@@ -101,7 +102,7 @@
 
 }  // namespace
 
-MemoryPressureMonitorChromeOS::MemoryPressureMonitorChromeOS(
+MemoryPressureMonitor::MemoryPressureMonitor(
     MemoryPressureThresholds thresholds)
     : current_memory_pressure_level_(
           MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
@@ -116,35 +117,41 @@
   LOG_IF(ERROR, !low_mem_file_.is_valid()) << "Cannot open kernel listener";
 }
 
-MemoryPressureMonitorChromeOS::~MemoryPressureMonitorChromeOS() {
+MemoryPressureMonitor::~MemoryPressureMonitor() {
   StopObserving();
 }
 
-void MemoryPressureMonitorChromeOS::ScheduleEarlyCheck() {
+void MemoryPressureMonitor::ScheduleEarlyCheck() {
   ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, Bind(&MemoryPressureMonitorChromeOS::CheckMemoryPressure,
+      FROM_HERE, Bind(&MemoryPressureMonitor::CheckMemoryPressure,
                       weak_ptr_factory_.GetWeakPtr()));
 }
 
 MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitorChromeOS::GetCurrentPressureLevel() const {
+MemoryPressureMonitor::GetCurrentPressureLevel() const {
   return current_memory_pressure_level_;
 }
 
-void MemoryPressureMonitorChromeOS::StartObserving() {
+// static
+MemoryPressureMonitor* MemoryPressureMonitor::Get() {
+  return static_cast<MemoryPressureMonitor*>(
+      base::MemoryPressureMonitor::Get());
+}
+
+void MemoryPressureMonitor::StartObserving() {
   timer_.Start(FROM_HERE,
                TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs),
-               Bind(&MemoryPressureMonitorChromeOS::
+               Bind(&MemoryPressureMonitor::
                         CheckMemoryPressureAndRecordStatistics,
                     weak_ptr_factory_.GetWeakPtr()));
 }
 
-void MemoryPressureMonitorChromeOS::StopObserving() {
+void MemoryPressureMonitor::StopObserving() {
   // If StartObserving failed, StopObserving will still get called.
   timer_.Stop();
 }
 
-void MemoryPressureMonitorChromeOS::CheckMemoryPressureAndRecordStatistics() {
+void MemoryPressureMonitor::CheckMemoryPressureAndRecordStatistics() {
   CheckMemoryPressure();
 
   // Record UMA histogram statistics for the current memory pressure level.
@@ -166,7 +173,7 @@
                             NUM_MEMORY_PRESSURE_LEVELS);
 }
 
-void MemoryPressureMonitorChromeOS::CheckMemoryPressure() {
+void MemoryPressureMonitor::CheckMemoryPressure() {
   MemoryPressureListener::MemoryPressureLevel old_pressure =
       current_memory_pressure_level_;
 
@@ -224,7 +231,7 @@
 }
 
 // Gets the used ChromeOS memory in percent.
-int MemoryPressureMonitorChromeOS::GetUsedMemoryInPercent() {
+int MemoryPressureMonitor::GetUsedMemoryInPercent() {
   base::SystemMemoryInfoKB info;
   if (!base::GetSystemMemoryInfo(&info)) {
     VLOG(1) << "Cannot determine the free memory of the system.";
@@ -261,4 +268,5 @@
   return percentage;
 }
 
+}  // namespace chromeos
 }  // namespace base
diff --git a/base/chromeos/memory_pressure_monitor_chromeos.h b/base/chromeos/memory_pressure_monitor.h
similarity index 83%
rename from base/chromeos/memory_pressure_monitor_chromeos.h
rename to base/chromeos/memory_pressure_monitor.h
index 45855eb..bed1ec3 100644
--- a/base/chromeos/memory_pressure_monitor_chromeos.h
+++ b/base/chromeos/memory_pressure_monitor.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
-#define BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
+#ifndef BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_H_
+#define BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_H_
 
 #include "base/base_export.h"
 #include "base/files/scoped_file.h"
@@ -15,17 +15,18 @@
 #include "base/timer/timer.h"
 
 namespace base {
+namespace chromeos {
 
 class TestMemoryPressureMonitor;
 
 ////////////////////////////////////////////////////////////////////////////////
-// MemoryPressureMonitorChromeOS
+// MemoryPressureMonitor
 //
 // A class to handle the observation of our free memory. It notifies the
 // MemoryPressureListener of memory fill level changes, so that it can take
 // action to reduce memory resources accordingly.
 //
-class BASE_EXPORT MemoryPressureMonitorChromeOS : public MemoryPressureMonitor {
+class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
  public:
   using GetUsedMemoryInPercentCallback = int (*)();
 
@@ -49,8 +50,8 @@
     THRESHOLD_AGGRESSIVE = 4
   };
 
-  explicit MemoryPressureMonitorChromeOS(MemoryPressureThresholds thresholds);
-  ~MemoryPressureMonitorChromeOS() override;
+  explicit MemoryPressureMonitor(MemoryPressureThresholds thresholds);
+  ~MemoryPressureMonitor() override;
 
   // Redo the memory pressure calculation soon and call again if a critical
   // memory pressure prevails. Note that this call will trigger an asynchronous
@@ -61,6 +62,10 @@
   MemoryPressureListener::MemoryPressureLevel GetCurrentPressureLevel() const
       override;
 
+  // Returns a type-casted version of the current memory pressure monitor. A
+  // simple wrapper to base::MemoryPressureMonitor::Get.
+  static MemoryPressureMonitor* Get();
+
  private:
   friend TestMemoryPressureMonitor;
   // Starts observing the memory fill level.
@@ -90,7 +95,7 @@
 
   // A periodic timer to check for resource pressure changes. This will get
   // replaced by a kernel triggered event system (see crbug.com/381196).
-  base::RepeatingTimer<MemoryPressureMonitorChromeOS> timer_;
+  base::RepeatingTimer<MemoryPressureMonitor> timer_;
 
   // To slow down the amount of moderate pressure event calls, this counter
   // gets used to count the number of events since the last event occured.
@@ -103,11 +108,12 @@
   // File descriptor used to detect low memory condition.
   ScopedFD low_mem_file_;
 
-  base::WeakPtrFactory<MemoryPressureMonitorChromeOS> weak_ptr_factory_;
+  base::WeakPtrFactory<MemoryPressureMonitor> weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitorChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
 };
 
+}  // namespace chromeos
 }  // namespace base
 
-#endif  // BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
+#endif  // BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_H_
diff --git a/base/chromeos/memory_pressure_monitor_chromeos_unittest.cc b/base/chromeos/memory_pressure_monitor_unittest.cc
similarity index 93%
rename from base/chromeos/memory_pressure_monitor_chromeos_unittest.cc
rename to base/chromeos/memory_pressure_monitor_unittest.cc
index 72e00d3..4fb8332 100644
--- a/base/chromeos/memory_pressure_monitor_chromeos_unittest.cc
+++ b/base/chromeos/memory_pressure_monitor_unittest.cc
@@ -3,12 +3,13 @@
 // found in the LICENSE file.
 
 #include "base/basictypes.h"
-#include "base/chromeos/memory_pressure_monitor_chromeos.h"
+#include "base/chromeos/memory_pressure_monitor.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/message_loop/message_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
+namespace chromeos {
 
 namespace {
 
@@ -40,12 +41,11 @@
 
 }  // namespace
 
-class TestMemoryPressureMonitor : public MemoryPressureMonitorChromeOS {
+class TestMemoryPressureMonitor : public MemoryPressureMonitor {
  public:
-  TestMemoryPressureMonitor() :
-    MemoryPressureMonitorChromeOS(
-        MemoryPressureMonitorChromeOS::THRESHOLD_DEFAULT),
-    memory_in_percent_override_(0) {
+  TestMemoryPressureMonitor()
+      : MemoryPressureMonitor(THRESHOLD_DEFAULT),
+        memory_in_percent_override_(0) {
     // Disable any timers which are going on and set a special memory reporting
     // function.
     StopObserving();
@@ -71,7 +71,7 @@
 
 // This test tests the various transition states from memory pressure, looking
 // for the correct behavior on event reposting as well as state updates.
-TEST(MemoryPressureMonitorChromeOSTest, CheckMemoryPressure) {
+TEST(ChromeOSMemoryPressureMonitorTest, CheckMemoryPressure) {
   base::MessageLoopForUI message_loop;
   scoped_ptr<TestMemoryPressureMonitor> monitor(
       new TestMemoryPressureMonitor);
@@ -161,4 +161,5 @@
   EXPECT_EQ(j, i);
 }
 
+}  // namespace chromeos
 }  // namespace base
diff --git a/base/debug/profiler.h b/base/debug/profiler.h
index c50555e..2920d8a 100644
--- a/base/debug/profiler.h
+++ b/base/debug/profiler.h
@@ -87,4 +87,4 @@
 }  // namespace debug
 }  // namespace base
 
-#endif  // BASE_DEBUG_PROFILER_H__
+#endif  // BASE_DEBUG_PROFILER_H_
diff --git a/base/file_version_info.h b/base/file_version_info.h
index 5bc577c..57b837c 100644
--- a/base/file_version_info.h
+++ b/base/file_version_info.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_FILE_VERSION_INFO_H__
-#define BASE_FILE_VERSION_INFO_H__
+#ifndef BASE_FILE_VERSION_INFO_H_
+#define BASE_FILE_VERSION_INFO_H_
 
 #include "build/build_config.h"
 
@@ -83,4 +83,4 @@
   virtual bool is_official_build() = 0;
 };
 
-#endif  // BASE_FILE_VERSION_INFO_H__
+#endif  // BASE_FILE_VERSION_INFO_H_
diff --git a/base/files/dir_reader_linux.h b/base/files/dir_reader_linux.h
index cb0cbd3..abf2595 100644
--- a/base/files/dir_reader_linux.h
+++ b/base/files/dir_reader_linux.h
@@ -95,4 +95,4 @@
 
 }  // namespace base
 
-#endif // BASE_FILES_DIR_READER_LINUX_H_
+#endif  // BASE_FILES_DIR_READER_LINUX_H_
diff --git a/base/files/dir_reader_posix.h b/base/files/dir_reader_posix.h
index 6a20ced..6a32d9f 100644
--- a/base/files/dir_reader_posix.h
+++ b/base/files/dir_reader_posix.h
@@ -33,4 +33,4 @@
 
 }  // namespace base
 
-#endif // BASE_FILES_DIR_READER_POSIX_H_
+#endif  // BASE_FILES_DIR_READER_POSIX_H_
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index e9a27bc..4d79be3 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -932,7 +932,7 @@
         return NULL;
       }
       NextNChars(kNullLen - 1);
-      return Value::CreateNullValue();
+      return Value::CreateNullValue().release();
     }
     default:
       ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
diff --git a/base/json/json_writer_unittest.cc b/base/json/json_writer_unittest.cc
index 802876c..5ac2590 100644
--- a/base/json/json_writer_unittest.cc
+++ b/base/json/json_writer_unittest.cc
@@ -12,8 +12,7 @@
   std::string output_js;
 
   // Test null.
-  scoped_ptr<Value> root(Value::CreateNullValue());
-  EXPECT_TRUE(JSONWriter::Write(root.get(), &output_js));
+  EXPECT_TRUE(JSONWriter::Write(Value::CreateNullValue().get(), &output_js));
   EXPECT_EQ("null", output_js);
 
   // Test empty dict.
@@ -57,7 +56,6 @@
   EXPECT_EQ("\"foo\"", output_js);
 }
 
-
 TEST(JSONWriterTest, NestedTypes) {
   std::string output_js;
 
diff --git a/base/json/string_escape_unittest.cc b/base/json/string_escape_unittest.cc
index 3eb4e8e..100373f 100644
--- a/base/json/string_escape_unittest.cc
+++ b/base/json/string_escape_unittest.cc
@@ -159,7 +159,7 @@
     const char* escaped;
   } cases[] = {
     {"b\x0f\x7f\xf0\xff!", "b\\u000F\\u007F\\u00F0\\u00FF!"},
-    {"\xe5\xc4\x4f\x05\xb6\xfd\0", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
+    {"\xe5\xc4\x4f\x05\xb6\xfd", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
   };
 
   for (size_t i = 0; i < arraysize(cases); ++i) {
diff --git a/sandbox/mac/dispatch_source_mach.cc b/base/mac/dispatch_source_mach.cc
similarity index 94%
rename from sandbox/mac/dispatch_source_mach.cc
rename to base/mac/dispatch_source_mach.cc
index a6f3ac8..745c9de 100644
--- a/sandbox/mac/dispatch_source_mach.cc
+++ b/base/mac/dispatch_source_mach.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "sandbox/mac/dispatch_source_mach.h"
+#include "base/mac/dispatch_source_mach.h"
 
-namespace sandbox {
+namespace base {
 
 DispatchSourceMach::DispatchSourceMach(const char* name,
                                        mach_port_t port,
@@ -59,4 +59,4 @@
   }
 }
 
-}  // namespace sandbox
+}  // namespace base
diff --git a/sandbox/mac/dispatch_source_mach.h b/base/mac/dispatch_source_mach.h
similarity index 87%
rename from sandbox/mac/dispatch_source_mach.h
rename to base/mac/dispatch_source_mach.h
index e3a3aa0..e7d5cb2 100644
--- a/sandbox/mac/dispatch_source_mach.h
+++ b/base/mac/dispatch_source_mach.h
@@ -2,21 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef SANDBOX_MAC_DISPATCH_SOURCE_MACH_H_
-#define SANDBOX_MAC_DISPATCH_SOURCE_MACH_H_
+#ifndef BASE_MAC_DISPATCH_SOURCE_MACH_H_
+#define BASE_MAC_DISPATCH_SOURCE_MACH_H_
 
 #include <dispatch/dispatch.h>
 
+#include "base/base_export.h"
 #include "base/macros.h"
-#include "sandbox/sandbox_export.h"
 
-namespace sandbox {
+namespace base {
 
 // This class encapsulates a MACH_RECV dispatch source. When this object is
 // destroyed, the source will be cancelled and it will wait for the source
 // to stop executing work. The source can run on either a user-supplied queue,
 // or it can create its own for the source.
-class SANDBOX_EXPORT DispatchSourceMach {
+class BASE_EXPORT DispatchSourceMach {
  public:
   // Creates a new dispatch source for the |port| and schedules it on a new
   // queue that will be created with |name|. When a Mach message is received,
@@ -56,6 +56,6 @@
   DISALLOW_COPY_AND_ASSIGN(DispatchSourceMach);
 };
 
-}  // namespace sandbox
+}  // namespace base
 
-#endif  // SANDBOX_MAC_DISPATCH_SOURCE_MACH_H_
+#endif  // BASE_MAC_DISPATCH_SOURCE_MACH_H_
diff --git a/sandbox/mac/dispatch_source_mach_unittest.cc b/base/mac/dispatch_source_mach_unittest.cc
similarity index 82%
rename from sandbox/mac/dispatch_source_mach_unittest.cc
rename to base/mac/dispatch_source_mach_unittest.cc
index 123a44c..82dc136 100644
--- a/sandbox/mac/dispatch_source_mach_unittest.cc
+++ b/base/mac/dispatch_source_mach_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "sandbox/mac/dispatch_source_mach.h"
+#include "base/mac/dispatch_source_mach.h"
 
 #include <mach/mach.h>
 
@@ -12,7 +12,7 @@
 #include "base/test/test_timeouts.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace sandbox {
+namespace base {
 
 class DispatchSourceMachTest : public testing::Test {
  public:
@@ -27,7 +27,7 @@
     send_right_.reset(port);
   }
 
-  mach_port_t port() { return receive_right_.get(); }
+  mach_port_t GetPort() { return receive_right_.get(); }
 
   void WaitForSemaphore(dispatch_semaphore_t semaphore) {
     dispatch_semaphore_wait(semaphore, dispatch_time(
@@ -42,13 +42,14 @@
 
 TEST_F(DispatchSourceMachTest, ReceiveAfterResume) {
   dispatch_semaphore_t signal = dispatch_semaphore_create(0);
+  mach_port_t port = GetPort();
 
   bool __block did_receive = false;
-  DispatchSourceMach source("org.chromium.sandbox.test.ReceiveAfterResume",
-      port(), ^{
+  DispatchSourceMach source("org.chromium.base.test.ReceiveAfterResume",
+      port, ^{
           mach_msg_empty_rcv_t msg = {{0}};
           msg.header.msgh_size = sizeof(msg);
-          msg.header.msgh_local_port = port();
+          msg.header.msgh_local_port = port;
           mach_msg_receive(&msg.header);
           did_receive = true;
 
@@ -57,7 +58,7 @@
 
   mach_msg_empty_send_t msg = {{0}};
   msg.header.msgh_size = sizeof(msg);
-  msg.header.msgh_remote_port = port();
+  msg.header.msgh_remote_port = port;
   msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
   ASSERT_EQ(KERN_SUCCESS, mach_msg_send(&msg.header));
 
@@ -66,20 +67,23 @@
   source.Resume();
 
   WaitForSemaphore(signal);
+  dispatch_release(signal);
 
   EXPECT_TRUE(did_receive);
 }
 
 TEST_F(DispatchSourceMachTest, NoMessagesAfterDestruction) {
+  mach_port_t port = GetPort();
+
   scoped_ptr<int> count(new int(0));
   int* __block count_ptr = count.get();
 
   scoped_ptr<DispatchSourceMach> source(new DispatchSourceMach(
-      "org.chromium.sandbox.test.NoMessagesAfterDestruction",
-      port(), ^{
+      "org.chromium.base.test.NoMessagesAfterDestruction",
+      port, ^{
           mach_msg_empty_rcv_t msg = {{0}};
           msg.header.msgh_size = sizeof(msg);
-          msg.header.msgh_local_port = port();
+          msg.header.msgh_local_port = port;
           mach_msg_receive(&msg.header);
           LOG(INFO) << "Receieve " << *count_ptr;
           ++(*count_ptr);
@@ -87,13 +91,13 @@
   source->Resume();
 
   dispatch_queue_t queue =
-      dispatch_queue_create("org.chromium.sandbox.test.MessageSend", NULL);
+      dispatch_queue_create("org.chromium.base.test.MessageSend", NULL);
   dispatch_semaphore_t signal = dispatch_semaphore_create(0);
   for (int i = 0; i < 30; ++i) {
     dispatch_async(queue, ^{
         mach_msg_empty_send_t msg = {{0}};
         msg.header.msgh_size = sizeof(msg);
-        msg.header.msgh_remote_port = port();
+        msg.header.msgh_remote_port = port;
         msg.header.msgh_bits =
             MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
         mach_msg_send(&msg.header);
@@ -113,7 +117,9 @@
   }
 
   WaitForSemaphore(signal);
+  dispatch_release(signal);
+
   dispatch_release(queue);
 }
 
-}  // namespace sandbox
+}  // namespace base
diff --git a/base/mac/memory_pressure_monitor_mac.cc b/base/mac/memory_pressure_monitor.cc
similarity index 87%
rename from base/mac/memory_pressure_monitor_mac.cc
rename to base/mac/memory_pressure_monitor.cc
index 81727bb..5667aa6 100644
--- a/base/mac/memory_pressure_monitor_mac.cc
+++ b/base/mac/memory_pressure_monitor.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/mac/memory_pressure_monitor_mac.h"
+#include "base/mac/memory_pressure_monitor.h"
 
 #include <dlfcn.h>
 #include <sys/sysctl.h>
@@ -10,9 +10,10 @@
 #include "base/mac/mac_util.h"
 
 namespace base {
+namespace mac {
 
 MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitorMac::MemoryPressureLevelForMacMemoryPressure(
+MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure(
     int mac_memory_pressure) {
   switch (mac_memory_pressure) {
     case DISPATCH_MEMORYPRESSURE_NORMAL:
@@ -25,7 +26,7 @@
   return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
 }
 
-void MemoryPressureMonitorMac::NotifyMemoryPressureChanged(
+void MemoryPressureMonitor::NotifyMemoryPressureChanged(
     dispatch_source_s* event_source) {
   int mac_memory_pressure = dispatch_source_get_data(event_source);
   MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
@@ -33,7 +34,7 @@
   MemoryPressureListener::NotifyMemoryPressure(memory_pressure_level);
 }
 
-MemoryPressureMonitorMac::MemoryPressureMonitorMac()
+MemoryPressureMonitor::MemoryPressureMonitor()
   : memory_level_event_source_(nullptr) {
   // _dispatch_source_type_memorypressure is not available prior to 10.9.
   dispatch_source_type_t dispatch_source_memorypressure =
@@ -58,11 +59,11 @@
   }
 }
 
-MemoryPressureMonitorMac::~MemoryPressureMonitorMac() {
+MemoryPressureMonitor::~MemoryPressureMonitor() {
 }
 
 MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitorMac::GetCurrentPressureLevel() const {
+MemoryPressureMonitor::GetCurrentPressureLevel() const {
   if (base::mac::IsOSMountainLionOrEarlier()) {
     return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
   }
@@ -73,4 +74,5 @@
   return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
 }
 
+}  // namespace mac
 }  // namespace base
diff --git a/base/mac/memory_pressure_monitor_mac.h b/base/mac/memory_pressure_monitor.h
similarity index 73%
rename from base/mac/memory_pressure_monitor_mac.h
rename to base/mac/memory_pressure_monitor.h
index aebdd65..afaec27 100644
--- a/base/mac/memory_pressure_monitor_mac.h
+++ b/base/mac/memory_pressure_monitor.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
-#define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
+#ifndef BASE_MAC_MEMORY_PRESSURE_MONITOR_H_
+#define BASE_MAC_MEMORY_PRESSURE_MONITOR_H_
 
 #include <dispatch/dispatch.h>
 
@@ -23,8 +23,9 @@
 #endif  // DISPATCH_MEMORYPRESSURE_NORMAL
 
 namespace base {
+namespace mac {
 
-class TestMemoryPressureMonitorMac;
+class TestMemoryPressureMonitor;
 
 struct DispatchSourceSDeleter {
   void operator()(dispatch_source_s* ptr) {
@@ -35,17 +36,16 @@
 
 // Declares the interface for the Mac MemoryPressureMonitor, which reports
 // memory pressure events and status.
-class BASE_EXPORT MemoryPressureMonitorMac : public MemoryPressureMonitor {
+class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
  public:
-  using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
-  MemoryPressureMonitorMac();
-  ~MemoryPressureMonitorMac() override;
+  MemoryPressureMonitor();
+  ~MemoryPressureMonitor() override;
 
   // Returns the currently-observed memory pressure.
   MemoryPressureLevel GetCurrentPressureLevel() const override;
 
  private:
-  friend TestMemoryPressureMonitorMac;
+  friend TestMemoryPressureMonitor;
 
   static MemoryPressureLevel
       MemoryPressureLevelForMacMemoryPressure(int mac_memory_pressure);
@@ -54,9 +54,10 @@
   scoped_ptr<dispatch_source_s, DispatchSourceSDeleter>
       memory_level_event_source_;
 
-  DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitorMac);
+  DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
 };
 
+}  // namespace mac
 }  // namespace base
 
-#endif  // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
+#endif  // BASE_MAC_MEMORY_PRESSURE_MONITOR_H_
diff --git a/base/mac/memory_pressure_monitor_mac_unittest.cc b/base/mac/memory_pressure_monitor_unittest.cc
similarity index 69%
rename from base/mac/memory_pressure_monitor_mac_unittest.cc
rename to base/mac/memory_pressure_monitor_unittest.cc
index 24ee09a..acb3666 100644
--- a/base/mac/memory_pressure_monitor_mac_unittest.cc
+++ b/base/mac/memory_pressure_monitor_unittest.cc
@@ -2,50 +2,51 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/mac/memory_pressure_monitor_mac.h"
+#include "base/mac/memory_pressure_monitor.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
+namespace mac {
 
-class TestMemoryPressureMonitorMac : public MemoryPressureMonitorMac {
+class TestMemoryPressureMonitor : public MemoryPressureMonitor {
  public:
-  using MemoryPressureMonitorMac::MemoryPressureLevelForMacMemoryPressure;
+  using MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure;
 
-  TestMemoryPressureMonitorMac() { }
+  TestMemoryPressureMonitor() { }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureMonitorMac);
+  DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureMonitor);
 };
 
-TEST(TestMemoryPressureMonitorMac, MemoryPressureFromMacMemoryPressure) {
+TEST(MacMemoryPressureMonitorTest, MemoryPressureFromMacMemoryPressure) {
   EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitorMac::
+            TestMemoryPressureMonitor::
                 MemoryPressureLevelForMacMemoryPressure(
                     DISPATCH_MEMORYPRESSURE_NORMAL));
   EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
-            TestMemoryPressureMonitorMac::
+            TestMemoryPressureMonitor::
                 MemoryPressureLevelForMacMemoryPressure(
                     DISPATCH_MEMORYPRESSURE_WARN));
   EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
-            TestMemoryPressureMonitorMac::
+            TestMemoryPressureMonitor::
                 MemoryPressureLevelForMacMemoryPressure(
                     DISPATCH_MEMORYPRESSURE_CRITICAL));
   EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitorMac::
+            TestMemoryPressureMonitor::
                 MemoryPressureLevelForMacMemoryPressure(0));
   EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitorMac::
+            TestMemoryPressureMonitor::
                 MemoryPressureLevelForMacMemoryPressure(3));
   EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitorMac::
+            TestMemoryPressureMonitor::
                 MemoryPressureLevelForMacMemoryPressure(5));
   EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitorMac::
+            TestMemoryPressureMonitor::
                 MemoryPressureLevelForMacMemoryPressure(-1));
 }
 
-TEST(TestMemoryPressureMonitorMac, CurrentMemoryPressure) {
-  TestMemoryPressureMonitorMac monitor;
+TEST(MacMemoryPressureMonitorTest, CurrentMemoryPressure) {
+  TestMemoryPressureMonitor monitor;
   MemoryPressureListener::MemoryPressureLevel memory_pressure =
       monitor.GetCurrentPressureLevel();
   EXPECT_TRUE(memory_pressure ==
@@ -56,4 +57,5 @@
                   MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
 }
 
+}  // namespace mac
 }  // namespace base
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
index d7be320..d70a6aa 100644
--- a/base/mac/sdk_forward_declarations.h
+++ b/base/mac/sdk_forward_declarations.h
@@ -244,6 +244,8 @@
 BASE_EXPORT extern NSString* const
     NSWindowDidChangeBackingPropertiesNotification;
 BASE_EXPORT extern NSString* const CBAdvertisementDataServiceDataKey;
+BASE_EXPORT extern NSString* const
+    NSPreferredScrollerStyleDidChangeNotification;
 #endif  // MAC_OS_X_VERSION_10_7
 
 #if !defined(MAC_OS_X_VERSION_10_9) || \
diff --git a/base/mac/sdk_forward_declarations.mm b/base/mac/sdk_forward_declarations.mm
index 347e87c..2e4b2d9 100644
--- a/base/mac/sdk_forward_declarations.mm
+++ b/base/mac/sdk_forward_declarations.mm
@@ -22,6 +22,9 @@
     @"NSWindowDidChangeBackingPropertiesNotification";
 
 NSString* const CBAdvertisementDataServiceDataKey = @"kCBAdvDataServiceData";
+
+NSString* const NSPreferredScrollerStyleDidChangeNotification =
+    @"NSPreferredScrollerStyleDidChangeNotification";
 #endif  // MAC_OS_X_VERSION_10_7
 
 #if !defined(MAC_OS_X_VERSION_10_9) || \
diff --git a/base/memory/memory_pressure_monitor.h b/base/memory/memory_pressure_monitor.h
index 50260c4..90c9420 100644
--- a/base/memory/memory_pressure_monitor.h
+++ b/base/memory/memory_pressure_monitor.h
@@ -10,6 +10,9 @@
 
 namespace base {
 
+// TODO(chrisha): Make this a concrete class with per-OS implementations rather
+// than an abstract base class.
+
 // Declares the interface for a MemoryPressureMonitor. There are multiple
 // OS specific implementations of this class. An instance of the memory
 // pressure observer is created at the process level, tracks memory usage, and
diff --git a/base/message_loop/message_pump_default.cc b/base/message_loop/message_pump_default.cc
index 27c19e0..bb9d8ce 100644
--- a/base/message_loop/message_pump_default.cc
+++ b/base/message_loop/message_pump_default.cc
@@ -52,7 +52,8 @@
       event_.Wait();
     } else {
       TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
-      if (delay > TimeDelta()) {
+      // If the delay is under 1 ms we need to execute the task right away.
+      if (delay.InMilliseconds() >= 1) {
         event_.TimedWait(delay);
       } else {
         // It looks like delayed_work_time_ indicates a time in the past, so we
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
index 39ecc30..fb069a5 100644
--- a/base/metrics/statistics_recorder.cc
+++ b/base/metrics/statistics_recorder.cc
@@ -286,8 +286,6 @@
 
 // static
 void StatisticsRecorder::DumpHistogramsToVlog(void* instance) {
-  DCHECK(VLOG_IS_ON(1));
-
   string output;
   StatisticsRecorder::WriteGraph(std::string(), &output);
   VLOG(1) << output;
diff --git a/base/observer_list.h b/base/observer_list.h
index 9ea344d..fb6f026 100644
--- a/base/observer_list.h
+++ b/base/observer_list.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_OBSERVER_LIST_H__
-#define BASE_OBSERVER_LIST_H__
+#ifndef BASE_OBSERVER_LIST_H_
+#define BASE_OBSERVER_LIST_H_
 
 #include <algorithm>
 #include <limits>
@@ -240,4 +240,4 @@
     }                                                                    \
   } while (0)
 
-#endif  // BASE_OBSERVER_LIST_H__
+#endif  // BASE_OBSERVER_LIST_H_
diff --git a/base/pickle.h b/base/pickle.h
index e6b9d81..9589e2a 100644
--- a/base/pickle.h
+++ b/base/pickle.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_PICKLE_H__
-#define BASE_PICKLE_H__
+#ifndef BASE_PICKLE_H_
+#define BASE_PICKLE_H_
 
 #include <string>
 
@@ -304,4 +304,4 @@
   FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextOverflow);
 };
 
-#endif  // BASE_PICKLE_H__
+#endif  // BASE_PICKLE_H_
diff --git a/base/prefs/json_pref_store.cc b/base/prefs/json_pref_store.cc
index 8ce5974..da545b8 100644
--- a/base/prefs/json_pref_store.cc
+++ b/base/prefs/json_pref_store.cc
@@ -150,17 +150,10 @@
     const base::FilePath& filename,
     const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
     scoped_ptr<PrefFilter> pref_filter)
-    : path_(filename),
-      sequenced_task_runner_(sequenced_task_runner),
-      prefs_(new base::DictionaryValue()),
-      read_only_(false),
-      writer_(filename, sequenced_task_runner),
-      pref_filter_(pref_filter.Pass()),
-      initialized_(false),
-      filtering_in_progress_(false),
-      read_error_(PREF_READ_ERROR_NONE),
-      write_count_histogram_(writer_.commit_interval(), path_) {
-  DCHECK(!path_.empty());
+    : JsonPrefStore(filename,
+                    base::FilePath(),
+                    sequenced_task_runner,
+                    pref_filter.Pass()) {
 }
 
 JsonPrefStore::JsonPrefStore(
@@ -177,6 +170,7 @@
       pref_filter_(pref_filter.Pass()),
       initialized_(false),
       filtering_in_progress_(false),
+      pending_lossy_write_(false),
       read_error_(PREF_READ_ERROR_NONE),
       write_count_histogram_(writer_.commit_interval(), path_) {
   DCHECK(!path_.empty());
@@ -236,7 +230,7 @@
   base::Value* old_value = NULL;
   prefs_->Get(key, &old_value);
   if (!old_value || !value->Equals(old_value)) {
-    prefs_->Set(key, new_value.release());
+    prefs_->Set(key, new_value.Pass());
     ReportValueChanged(key, flags);
   }
 }
@@ -251,9 +245,8 @@
   base::Value* old_value = NULL;
   prefs_->Get(key, &old_value);
   if (!old_value || !value->Equals(old_value)) {
-    prefs_->Set(key, new_value.release());
-    if (!read_only_)
-      writer_.ScheduleWrite(this);
+    prefs_->Set(key, new_value.Pass());
+    ScheduleWrite(flags);
   }
 }
 
@@ -268,8 +261,7 @@
   DCHECK(CalledOnValidThread());
 
   prefs_->RemovePath(key, NULL);
-  if (!read_only_)
-    writer_.ScheduleWrite(this);
+  ScheduleWrite(flags);
 }
 
 bool JsonPrefStore::ReadOnly() const {
@@ -309,6 +301,11 @@
 void JsonPrefStore::CommitPendingWrite() {
   DCHECK(CalledOnValidThread());
 
+  // Schedule a write for any lossy writes that are outstanding to ensure that
+  // they get flushed when this function is called.
+  if (pending_lossy_write_)
+    writer_.ScheduleWrite(this);
+
   if (writer_.HasPendingWrite() && !read_only_)
     writer_.DoScheduledWrite();
 }
@@ -321,8 +318,7 @@
 
   FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
 
-  if (!read_only_)
-    writer_.ScheduleWrite(this);
+  ScheduleWrite(flags);
 }
 
 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback(
@@ -401,6 +397,8 @@
 bool JsonPrefStore::SerializeData(std::string* output) {
   DCHECK(CalledOnValidThread());
 
+  pending_lossy_write_ = false;
+
   write_count_histogram_.RecordWriteOccured();
 
   if (pref_filter_)
@@ -432,8 +430,8 @@
 
   initialized_ = true;
 
-  if (schedule_write && !read_only_)
-    writer_.ScheduleWrite(this);
+  if (schedule_write)
+    ScheduleWrite(DEFAULT_PREF_WRITE_FLAGS);
 
   if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE)
     error_delegate_->OnError(read_error_);
@@ -445,6 +443,16 @@
   return;
 }
 
+void JsonPrefStore::ScheduleWrite(uint32 flags) {
+  if (read_only_)
+    return;
+
+  if (flags & LOSSY_PREF_WRITE_FLAG)
+    pending_lossy_write_ = true;
+  else
+    writer_.ScheduleWrite(this);
+}
+
 // NOTE: This value should NOT be changed without renaming the histogram
 // otherwise it will create incompatible buckets.
 const int32_t
diff --git a/base/prefs/json_pref_store.h b/base/prefs/json_pref_store.h
index 2ad546d..ef260eb 100644
--- a/base/prefs/json_pref_store.h
+++ b/base/prefs/json_pref_store.h
@@ -29,6 +29,7 @@
 class DictionaryValue;
 class FilePath;
 class HistogramBase;
+class JsonPrefStoreLossyWriteTest;
 class SequencedTaskRunner;
 class SequencedWorkerPool;
 class Value;
@@ -165,6 +166,7 @@
                            WriteCountHistogramTestMultiplePeriods);
   FRIEND_TEST_ALL_PREFIXES(base::JsonPrefStoreTest,
                            WriteCountHistogramTestPeriodWithGaps);
+  friend class base::JsonPrefStoreLossyWriteTest;
 
   ~JsonPrefStore() override;
 
@@ -190,6 +192,10 @@
                         scoped_ptr<base::DictionaryValue> prefs,
                         bool schedule_write);
 
+  // Schedule a write with the file writer as long as |flags| doesn't contain
+  // WriteablePrefStore::LOSSY_PREF_WRITE_FLAG.
+  void ScheduleWrite(uint32 flags);
+
   const base::FilePath path_;
   const base::FilePath alternate_path_;
   const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
@@ -208,6 +214,7 @@
 
   bool initialized_;
   bool filtering_in_progress_;
+  bool pending_lossy_write_;
   PrefReadError read_error_;
 
   std::set<std::string> keys_need_empty_value_;
diff --git a/base/prefs/json_pref_store_unittest.cc b/base/prefs/json_pref_store_unittest.cc
index 0fab868..67a8adb 100644
--- a/base/prefs/json_pref_store_unittest.cc
+++ b/base/prefs/json_pref_store_unittest.cc
@@ -108,9 +108,7 @@
   void TearDown() override {
     // Make sure all pending tasks have been processed (e.g., deleting the
     // JsonPrefStore may post write tasks).
-    message_loop_.task_runner()->PostTask(FROM_HERE,
-                                          MessageLoop::QuitWhenIdleClosure());
-    message_loop_.Run();
+    RunLoop().RunUntilIdle();
   }
 
   // The path to temporary directory used to contain the test operations.
@@ -127,7 +125,7 @@
 
 // Test fallback behavior for a nonexistent file.
 TEST_F(JsonPrefStoreTest, NonExistentFile) {
-  base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+  base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
   ASSERT_FALSE(PathExists(bogus_input_file));
   scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
       bogus_input_file, message_loop_.task_runner(), scoped_ptr<PrefFilter>());
@@ -138,9 +136,9 @@
 
 // Test fallback behavior for a nonexistent file and alternate file.
 TEST_F(JsonPrefStoreTest, NonExistentFileAndAlternateFile) {
-  base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+  base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
   base::FilePath bogus_alternate_input_file =
-      data_dir_.AppendASCII("read_alternate.txt");
+      temp_dir_.path().AppendASCII("read_alternate.txt");
   ASSERT_FALSE(PathExists(bogus_input_file));
   ASSERT_FALSE(PathExists(bogus_alternate_input_file));
   scoped_refptr<JsonPrefStore> pref_store =
@@ -321,7 +319,7 @@
 
   // Write to file.
   pref_store->CommitPendingWrite();
-  MessageLoop::current()->RunUntilIdle();
+  RunLoop().RunUntilIdle();
 
   // Reload.
   pref_store = new JsonPrefStore(pref_file, message_loop_.task_runner(),
@@ -360,7 +358,7 @@
 
 // Tests asynchronous reading of the file when there is no file.
 TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) {
-  base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+  base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
   ASSERT_FALSE(PathExists(bogus_input_file));
   scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
       bogus_input_file, message_loop_.task_runner(), scoped_ptr<PrefFilter>());
@@ -809,4 +807,125 @@
   ASSERT_EQ(6, samples->TotalCount());
 }
 
+class JsonPrefStoreLossyWriteTest : public JsonPrefStoreTest {
+ protected:
+  void SetUp() override {
+    JsonPrefStoreTest::SetUp();
+    test_file_ = temp_dir_.path().AppendASCII("test.json");
+  }
+
+  // Creates a JsonPrefStore with the given |file_writer|.
+  scoped_refptr<JsonPrefStore> CreatePrefStore() {
+    return new JsonPrefStore(test_file_, message_loop_.task_runner(),
+                             scoped_ptr<PrefFilter>());
+  }
+
+  // Return the ImportantFileWriter for a given JsonPrefStore.
+  ImportantFileWriter* GetImportantFileWriter(
+      scoped_refptr<JsonPrefStore> pref_store) {
+    return &(pref_store->writer_);
+  }
+
+  // Get the contents of kTestFile. Pumps the message loop before returning the
+  // result.
+  std::string GetTestFileContents() {
+    RunLoop().RunUntilIdle();
+    std::string file_contents;
+    ReadFileToString(test_file_, &file_contents);
+    return file_contents;
+  }
+
+ private:
+  base::FilePath test_file_;
+};
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteBasic) {
+  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+  // Set a normal pref and check that it gets scheduled to be written.
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->SetValue("normal", new base::StringValue("normal"),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  ASSERT_TRUE(file_writer->HasPendingWrite());
+  file_writer->DoScheduledWrite();
+  ASSERT_EQ("{\"normal\":\"normal\"}", GetTestFileContents());
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // Set a lossy pref and check that it is not scheduled to be written.
+  // SetValue/RemoveValue.
+  pref_store->SetValue("lossy", new base::StringValue("lossy"),
+                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->RemoveValue("lossy", WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // SetValueSilently/RemoveValueSilently.
+  pref_store->SetValueSilently("lossy", new base::StringValue("lossy"),
+                               WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->RemoveValueSilently("lossy",
+                                  WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // ReportValueChanged.
+  pref_store->SetValue("lossy", new base::StringValue("lossy"),
+                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->ReportValueChanged("lossy",
+                                 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // Call CommitPendingWrite and check that the lossy pref and the normal pref
+  // are there with the last values set above.
+  pref_store->CommitPendingWrite();
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+            GetTestFileContents());
+}
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossyFirst) {
+  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+  // Set a lossy pref and check that it is not scheduled to be written.
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->SetValue("lossy", new base::StringValue("lossy"),
+                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // Set a normal pref and check that it is scheduled to be written.
+  pref_store->SetValue("normal", new base::StringValue("normal"),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  ASSERT_TRUE(file_writer->HasPendingWrite());
+
+  // Call DoScheduledWrite and check both prefs get written.
+  file_writer->DoScheduledWrite();
+  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+            GetTestFileContents());
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+}
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossySecond) {
+  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+  // Set a normal pref and check that it is scheduled to be written.
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->SetValue("normal", new base::StringValue("normal"),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  ASSERT_TRUE(file_writer->HasPendingWrite());
+
+  // Set a lossy pref and check that the write is still scheduled.
+  pref_store->SetValue("lossy", new base::StringValue("lossy"),
+                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_TRUE(file_writer->HasPendingWrite());
+
+  // Call DoScheduledWrite and check both prefs get written.
+  file_writer->DoScheduledWrite();
+  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+            GetTestFileContents());
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+}
+
 }  // namespace base
diff --git a/base/prefs/pref_service.cc b/base/prefs/pref_service.cc
index ad23157..6e1d58c 100644
--- a/base/prefs/pref_service.cc
+++ b/base/prefs/pref_service.cc
@@ -190,8 +190,7 @@
   DCHECK(CalledOnValidThread());
   scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
   for (const auto& it : *pref_registry_) {
-    const base::Value* value = GetPreferenceValue(it.first);
-    out->Set(it.first, value->DeepCopy());
+    out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
   }
   return out.Pass();
 }
@@ -204,7 +203,7 @@
     const Preference* pref = FindPreference(it.first);
     if (pref->IsDefaultValue())
       continue;
-    out->Set(it.first, pref->GetValue()->DeepCopy());
+    out->Set(it.first, pref->GetValue()->CreateDeepCopy());
   }
   return out.Pass();
 }
@@ -216,7 +215,7 @@
   for (const auto& it : *pref_registry_) {
     const base::Value* value = GetPreferenceValue(it.first);
     DCHECK(value);
-    out->SetWithoutPathExpansion(it.first, value->DeepCopy());
+    out->SetWithoutPathExpansion(it.first, value->CreateDeepCopy());
   }
   return out.Pass();
 }
diff --git a/base/profiler/scoped_profile.h b/base/profiler/scoped_profile.h
index 6b0c800..2c4105d 100644
--- a/base/profiler/scoped_profile.h
+++ b/base/profiler/scoped_profile.h
@@ -62,4 +62,4 @@
 
 }  // namespace tracked_objects
 
-#endif   // BASE_PROFILER_SCOPED_PROFILE_H_
+#endif  // BASE_PROFILER_SCOPED_PROFILE_H_
diff --git a/base/test/values_test_util.cc b/base/test/values_test_util.cc
index c5dfd79..3e762b9 100644
--- a/base/test/values_test_util.cc
+++ b/base/test/values_test_util.cc
@@ -69,7 +69,7 @@
       NULL, &error_msg));
   if (!result) {
     ADD_FAILURE() << "Failed to parse \"" << json << "\": " << error_msg;
-    result.reset(Value::CreateNullValue());
+    result = Value::CreateNullValue();
   }
   return result.Pass();
 }
diff --git a/base/trace_event/memory_dump_request_args.h b/base/trace_event/memory_dump_request_args.h
index 4fb0335..4d3763a 100644
--- a/base/trace_event/memory_dump_request_args.h
+++ b/base/trace_event/memory_dump_request_args.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
+#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
+#define BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
 
 // This file defines the types and structs used to issue memory dump requests.
 // These are also used in the IPCs for coordinating inter-process memory dumps.
@@ -38,4 +38,4 @@
 }  // namespace trace_event
 }  // namespace base
 
-#endif  // BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
+#endif  // BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
diff --git a/base/trace_event/trace_event_etw_export_win.cc b/base/trace_event/trace_event_etw_export_win.cc
index 1cb3b8c..28c154c 100644
--- a/base/trace_event/trace_event_etw_export_win.cc
+++ b/base/trace_event/trace_event_etw_export_win.cc
@@ -132,7 +132,9 @@
       !EventEnabledChromeEvent())
     return;
 
-  std::string phase_string;
+  const char* phase_string = nullptr;
+  // Space to store the phase identifier and null-terminator, when needed.
+  char phase_buffer[2];
   switch (phase) {
     case TRACE_EVENT_PHASE_BEGIN:
       phase_string = "Begin";
@@ -195,14 +197,20 @@
       phase_string = "Phase Delete Object";
       break;
     default:
-      phase_string.push_back(phase);
+      phase_buffer[0] = phase;
+      phase_buffer[1] = 0;
+      phase_string = phase_buffer;
       break;
   }
 
   std::string arg_values_string[3];
   for (int i = 0; i < num_args; i++) {
     if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
-      convertable_values[i]->AppendAsTraceFormat(arg_values_string + i);
+      // Temporarily do nothing here. This function consumes 1/3 to 1/2 of
+      // *total* process CPU time when ETW tracing, and many of the strings
+      // created exceed WPA's 4094 byte limit and are shown as:
+      // "Unable to parse data". See crbug.com/488257
+      //convertable_values[i]->AppendAsTraceFormat(arg_values_string + i);
     } else {
       TraceEvent::TraceValue trace_event;
       trace_event.as_uint = arg_values[i];
@@ -212,7 +220,7 @@
   }
 
   EventWriteChromeEvent(
-      name, phase_string.c_str(), num_args > 0 ? arg_names[0] : "",
+      name, phase_string, num_args > 0 ? arg_names[0] : "",
       arg_values_string[0].c_str(), num_args > 1 ? arg_names[1] : "",
       arg_values_string[1].c_str(), num_args > 2 ? arg_names[2] : "",
       arg_values_string[2].c_str());
diff --git a/base/trace_event/trace_event_etw_export_win.h b/base/trace_event/trace_event_etw_export_win.h
index 3d26b33..eefe820 100644
--- a/base/trace_event/trace_event_etw_export_win.h
+++ b/base/trace_event/trace_event_etw_export_win.h
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 // This file contains the Windows-specific exporting to ETW.
-#ifndef BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
-#define BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
+#ifndef BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
+#define BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
 
 #include "base/base_export.h"
 #include "base/trace_event/trace_event_impl.h"
@@ -72,4 +72,4 @@
 }  // namespace trace_event
 }  // namespace base
 
-#endif  // BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
+#endif  // BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
diff --git a/base/tuple.h b/base/tuple.h
index 88c3075..4628aa9 100644
--- a/base/tuple.h
+++ b/base/tuple.h
@@ -25,8 +25,8 @@
 //   DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3));
 //   // foo->SomeMeth(1, 2, 3);
 
-#ifndef BASE_TUPLE_H__
-#define BASE_TUPLE_H__
+#ifndef BASE_TUPLE_H_
+#define BASE_TUPLE_H_
 
 #include "base/bind_helpers.h"
 
@@ -329,4 +329,4 @@
                        MakeIndexSequence<sizeof...(OutTs)>());
 }
 
-#endif  // BASE_TUPLE_H__
+#endif  // BASE_TUPLE_H_
diff --git a/base/values.cc b/base/values.cc
index f448f51..4093eba 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -85,8 +85,8 @@
 }
 
 // static
-Value* Value::CreateNullValue() {
-  return new Value(TYPE_NULL);
+scoped_ptr<Value> Value::CreateNullValue() {
+  return make_scoped_ptr(new Value(TYPE_NULL));
 }
 
 bool Value::GetAsBinary(const BinaryValue** out_value) const {
@@ -137,7 +137,7 @@
   // This method should only be getting called for null Values--all subclasses
   // need to provide their own implementation;.
   DCHECK(IsType(TYPE_NULL));
-  return CreateNullValue();
+  return CreateNullValue().release();
 }
 
 scoped_ptr<Value> Value::CreateDeepCopy() const {
@@ -1137,6 +1137,10 @@
   return result;
 }
 
+scoped_ptr<ListValue> ListValue::CreateDeepCopy() const {
+  return make_scoped_ptr(DeepCopy());
+}
+
 bool ListValue::Equals(const Value* other) const {
   if (other->GetType() != GetType())
     return false;
diff --git a/base/values.h b/base/values.h
index ca046f1..e32edec 100644
--- a/base/values.h
+++ b/base/values.h
@@ -64,7 +64,7 @@
 
   virtual ~Value();
 
-  static Value* CreateNullValue();
+  static scoped_ptr<Value> CreateNullValue();
 
   // Returns the type of the value stored by the current Value object.
   // Each type will be implemented by only one subclass of Value, so it's
@@ -494,6 +494,9 @@
   ListValue* DeepCopy() const override;
   bool Equals(const Value* other) const override;
 
+  // Preferred version of DeepCopy. TODO(estade): remove DeepCopy.
+  scoped_ptr<ListValue> CreateDeepCopy() const;
+
  private:
   ValueVector list_;
 
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index b365a22..6466a96 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -320,9 +320,8 @@
 
 TEST(ValuesTest, DictionaryWithoutPathExpansion) {
   DictionaryValue dict;
-  dict.Set("this.is.expanded", make_scoped_ptr(Value::CreateNullValue()));
-  dict.SetWithoutPathExpansion("this.isnt.expanded",
-                               make_scoped_ptr(Value::CreateNullValue()));
+  dict.Set("this.is.expanded", Value::CreateNullValue());
+  dict.SetWithoutPathExpansion("this.isnt.expanded", Value::CreateNullValue());
 
   EXPECT_FALSE(dict.HasKey("this.is.expanded"));
   EXPECT_TRUE(dict.HasKey("this"));
@@ -392,7 +391,7 @@
 
 TEST(ValuesTest, DeepCopy) {
   DictionaryValue original_dict;
-  scoped_ptr<Value> scoped_null(Value::CreateNullValue());
+  scoped_ptr<Value> scoped_null = Value::CreateNullValue();
   Value* original_null = scoped_null.get();
   original_dict.Set("null", scoped_null.Pass());
   scoped_ptr<FundamentalValue> scoped_bool(new FundamentalValue(true));
@@ -549,8 +548,8 @@
   EXPECT_NE(null1.get(), null2.get());
   EXPECT_TRUE(null1->Equals(null2.get()));
 
-  scoped_ptr<Value> boolean(new FundamentalValue(false));
-  EXPECT_FALSE(null1->Equals(boolean.get()));
+  FundamentalValue boolean(false);
+  EXPECT_FALSE(null1->Equals(&boolean));
 
   DictionaryValue dv;
   dv.SetBoolean("a", false);
@@ -558,14 +557,14 @@
   dv.SetDouble("c", 2.5);
   dv.SetString("d1", "string");
   dv.SetString("d2", ASCIIToUTF16("http://google.com"));
-  dv.Set("e", make_scoped_ptr(Value::CreateNullValue()));
+  dv.Set("e", Value::CreateNullValue());
 
   scoped_ptr<DictionaryValue> copy = dv.CreateDeepCopy();
   EXPECT_TRUE(dv.Equals(copy.get()));
 
   scoped_ptr<ListValue> list(new ListValue);
   ListValue* original_list = list.get();
-  list->Append(make_scoped_ptr(Value::CreateNullValue()));
+  list->Append(Value::CreateNullValue());
   list->Append(make_scoped_ptr(new DictionaryValue));
   scoped_ptr<Value> list_copy(list->CreateDeepCopy());
 
diff --git a/base/win/resource_util.h b/base/win/resource_util.h
index f3444ae..8a8baa0 100644
--- a/base/win/resource_util.h
+++ b/base/win/resource_util.h
@@ -5,8 +5,8 @@
 // This file contains utility functions for accessing resources in external
 // files (DLLs) or embedded in the executable itself.
 
-#ifndef BASE_WIN_RESOURCE_UTIL_H__
-#define BASE_WIN_RESOURCE_UTIL_H__
+#ifndef BASE_WIN_RESOURCE_UTIL_H_
+#define BASE_WIN_RESOURCE_UTIL_H_
 
 #include <windows.h>
 
@@ -36,4 +36,4 @@
 }  // namespace win
 }  // namespace base
 
-#endif  // BASE_WIN_RESOURCE_UTIL_H__
+#endif  // BASE_WIN_RESOURCE_UTIL_H_
diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc
index 2ebef32..ce944e4 100644
--- a/base/win/scoped_handle.cc
+++ b/base/win/scoped_handle.cc
@@ -152,6 +152,12 @@
   if (!enabled_)
     return;
 
+  // Idea here is to make our handles non-closable until we close it ourselves.
+  // Handles provided could be totally fabricated especially through our
+  // unittest, we are ignoring that for now by not checking return value.
+  ::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE,
+                         HANDLE_FLAG_PROTECT_FROM_CLOSE);
+
   // Grab the thread id before the lock.
   DWORD thread_id = GetCurrentThreadId();
 
@@ -172,6 +178,15 @@
   if (!enabled_)
     return;
 
+  // We expect handle to be protected till this point.
+  DWORD flags = 0;
+  if (::GetHandleInformation(handle, &flags)) {
+    CHECK_NE(0U, (flags & HANDLE_FLAG_PROTECT_FROM_CLOSE));
+
+    // Unprotect handle so that it could be closed.
+    ::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
+  }
+
   AutoNativeLock lock(*lock_);
   HandleMap::iterator i = map_.find(handle);
   if (i == map_.end())
diff --git a/base/win/startup_information.h b/base/win/startup_information.h
index 73d9f3e..3f18ee5 100644
--- a/base/win/startup_information.h
+++ b/base/win/startup_information.h
@@ -47,4 +47,4 @@
 }  // namespace win
 }  // namespace base
 
-#endif  // BASE_WIN_STARTUP_INFORMATION_H__
+#endif  // BASE_WIN_STARTUP_INFORMATION_H_
diff --git a/build/all.gyp b/build/all.gyp
index 1866c2e..4d79a84 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -319,10 +319,14 @@
         '../ui/base/ui_base_tests.gyp:ui_base_unittests',
         '../ui/display/display.gyp:display_unittests',
         '../ui/gfx/gfx_tests.gyp:gfx_unittests',
-        '../ui/gl/gl_tests.gyp:gl_unittests',
         '../url/url.gyp:url_unittests',
       ],
       'conditions': [
+        ['OS!="ios"', {
+          'dependencies': [
+            '../ui/gl/gl_tests.gyp:gl_unittests',
+          ],
+        }],
         ['OS!="ios" and OS!="mac"', {
           'dependencies': [
             '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
@@ -485,6 +489,11 @@
             '../components/nacl.gyp:nacl_loader_unittests',
           ],
         }],
+        ['disable_nacl==0 and disable_nacl_untrusted==0 and OS=="linux"', {
+          'dependencies': [
+            '../components/nacl_nonsfi.gyp:nacl_helper_nonsfi_unittests',
+          ],
+        }],
         ['disable_nacl==0 and disable_nacl_untrusted==0', {
           'dependencies': [
             '../mojo/mojo_nacl_untrusted.gyp:libmojo',
diff --git a/build/android/adb_install_apk.py b/build/android/adb_install_apk.py
index 7bc634c..00bd38e 100755
--- a/build/android/adb_install_apk.py
+++ b/build/android/adb_install_apk.py
@@ -11,6 +11,7 @@
 import sys
 
 from pylib import constants
+from pylib.device import device_errors
 from pylib.device import device_utils
 
 
@@ -73,14 +74,11 @@
   devices = device_utils.DeviceUtils.HealthyDevices()
 
   if options.device:
-    device_serials = [d.adb.GetDeviceSerial() for d in devices]
-    if options.device not in device_serials:
-      raise Exception('Error: %s not in attached devices %s' % (options.device,
-                      ','.join(device_serials)))
-    devices = [options.device]
-
-  if not devices:
-    raise Exception('Error: no connected devices')
+    devices = [d for d in devices if d == options.device]
+    if not devices:
+      raise device_errors.DeviceUnreachableError(options.device)
+  elif not devices:
+    raise device_errors.NoDevicesError()
 
   device_utils.DeviceUtils.parallel(devices).Install(
       options.apk, reinstall=options.keep_data)
diff --git a/build/android/adb_reverse_forwarder.py b/build/android/adb_reverse_forwarder.py
index 6cae0cf..3ce5359 100755
--- a/build/android/adb_reverse_forwarder.py
+++ b/build/android/adb_reverse_forwarder.py
@@ -19,6 +19,7 @@
 from pylib import constants
 from pylib import forwarder
 from pylib.device import adb_wrapper
+from pylib.device import device_errors
 from pylib.device import device_utils
 from pylib.utils import run_tests_helper
 
@@ -56,16 +57,15 @@
   devices = device_utils.DeviceUtils.HealthyDevices()
 
   if options.device:
-    if options.device not in [str(d) for d in devices]:
-      raise Exception('Error: %s not in attached devices %s' % (options.device,
-                      ','.join(devices)))
-    devices = [options.device]
-  else:
-    if not devices:
-      raise Exception('Error: no connected devices')
+    device = next((d for d in devices if d == options.device), None)
+    if not device:
+      raise device_errors.DeviceUnreachableError(options.device)
+  elif devices:
+    device = devices[0]
     logging.info('No device specified. Defaulting to %s', devices[0])
+  else:
+    raise device_errors.NoDevicesError()
 
-  device = devices[0]
   constants.SetBuildType(options.build_type)
   try:
     forwarder.Forwarder.Map(port_pairs, device)
diff --git a/build/android/buildbot/bb_device_steps.py b/build/android/buildbot/bb_device_steps.py
index 53646e3..665c736 100755
--- a/build/android/buildbot/bb_device_steps.py
+++ b/build/android/buildbot/bb_device_steps.py
@@ -18,7 +18,6 @@
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
 import provision_devices
-from pylib import android_commands
 from pylib import constants
 from pylib.device import device_utils
 from pylib.gtest import gtest_config
@@ -100,6 +99,7 @@
     'chrome_proxy',
     'components_browsertests',
     'gfx_unittests',
+    'gl_unittests',
     'gpu',
     'python_unittests',
     'telemetry_unittests',
@@ -214,9 +214,9 @@
   """
   InstallApk(options, INSTRUMENTATION_TESTS['ChromeShell'], False)
   args = ['--browser', 'android-chrome-shell']
-  devices = android_commands.GetAttachedDevices()
+  devices = device_utils.DeviceUtils.HealthyDevices()
   if devices:
-    args = args + ['--device', devices[0]]
+    args = args + ['--device', devices[0].adb.GetDeviceSerial()]
   bb_annotations.PrintNamedStep('chrome_proxy')
   RunCmd(['tools/chrome_proxy/run_tests'] + args)
 
@@ -233,7 +233,7 @@
   """
   InstallApk(options, INSTRUMENTATION_TESTS['ChromeShell'], False)
   args = ['--browser', 'android-chrome-shell']
-  devices = android_commands.GetAttachedDevices()
+  devices = device_utils.DeviceUtils.HealthyDevices()
   if devices:
     args = args + ['--device', 'android']
   bb_annotations.PrintNamedStep(step_name)
@@ -585,6 +585,8 @@
           lambda options: RunTestSuites(options, ['components_browsertests'])),
       ('gfx_unittests',
           lambda options: RunTestSuites(options, ['gfx_unittests'])),
+      ('gl_unittests',
+          lambda options: RunTestSuites(options, ['gl_unittests'])),
       ('gpu', RunGPUTests),
       ('python_unittests', RunPythonUnitTests),
       ('telemetry_unittests', RunTelemetryUnitTests),
diff --git a/build/android/buildbot/bb_run_bot.py b/build/android/buildbot/bb_run_bot.py
index 2b5f31a..0c8a977 100755
--- a/build/android/buildbot/bb_run_bot.py
+++ b/build/android/buildbot/bb_run_bot.py
@@ -128,6 +128,7 @@
       'base_junit_tests',
       'components_browsertests',
       'gfx_unittests',
+      'gl_unittests',
   ]
   flakiness_server = (
       '--flakiness-server=%s' % constants.UPSTREAM_FLAKINESS_SERVER)
diff --git a/build/android/gyp/apk_install.py b/build/android/gyp/apk_install.py
index 19a217c..419dc17 100755
--- a/build/android/gyp/apk_install.py
+++ b/build/android/gyp/apk_install.py
@@ -58,6 +58,10 @@
   parser = optparse.OptionParser()
   parser.add_option('--apk-path',
       help='Path to .apk to install.')
+  parser.add_option('--split-apk-path',
+      help='Path to .apk splits (can specify multiple times, causes '
+      '--install-multiple to be used.',
+      action='append')
   parser.add_option('--install-record',
       help='Path to install record (touched only when APK is installed).')
   parser.add_option('--build-device-configuration',
@@ -85,7 +89,15 @@
   force_install = HasInstallMetadataChanged(device, apk_package, metadata_path)
 
   def Install():
-    device.Install(options.apk_path, reinstall=True)
+    # TODO: Filter splits using split-select.
+    active_splits = options.split_apk_path
+    if active_splits:
+      device.adb.InstallMultiple(
+          [options.apk_path] + active_splits,
+          reinstall=True)
+    else:
+      device.Install(options.apk_path, reinstall=True)
+
     RecordInstallMetadata(device, apk_package, metadata_path)
     build_utils.Touch(options.install_record)
 
diff --git a/build/android/gyp/generate_split_manifest.py b/build/android/gyp/generate_split_manifest.py
new file mode 100755
index 0000000..1c84fe7
--- /dev/null
+++ b/build/android/gyp/generate_split_manifest.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+#
+# Copyright 2015 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.
+"""Creates an AndroidManifest.xml for an APK split.
+
+Given the manifest file for the main APK, generates an AndroidManifest.xml with
+the value required for a Split APK (package, versionCode, etc).
+"""
+
+import lxml.etree
+import optparse
+
+from util import build_utils
+
+MANIFEST_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?>
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="%(package)s"
+    split="%(split)s">
+  <application android:hasCode="%(has_code)s">
+  </application>
+</manifest>
+"""
+
+def ParseArgs():
+  """Parses command line options.
+
+  Returns:
+    An options object as from optparse.OptionsParser.parse_args()
+  """
+  parser = optparse.OptionParser()
+  build_utils.AddDepfileOption(parser)
+  parser.add_option('--main-manifest', help='The main manifest of the app')
+  parser.add_option('--out-manifest', help='The output manifest')
+  parser.add_option('--split', help='The name of the split')
+  parser.add_option(
+      '--has-code',
+      action='store_true',
+      default=False,
+      help='Whether the split will contain a .dex file')
+
+  (options, args) = parser.parse_args()
+
+  if args:
+    parser.error('No positional arguments should be given.')
+
+  # Check that required options have been provided.
+  required_options = ('main_manifest', 'out_manifest', 'split')
+  build_utils.CheckOptions(options, parser, required=required_options)
+
+  return options
+
+
+def Build(main_manifest, split, has_code):
+  """Builds a split manifest based on the manifest of the main APK.
+
+  Args:
+    main_manifest: the XML manifest of the main APK as a string
+    split: the name of the split as a string
+    has_code: whether this split APK will contain .dex files
+
+  Returns:
+    The XML split manifest as a string
+  """
+
+  doc = lxml.etree.fromstring(main_manifest)
+  package = doc.xpath('/manifest/@package')[0]
+
+  return MANIFEST_TEMPLATE % {
+      'package': package,
+      'split': split.replace('-', '_'),
+      'has_code': str(has_code).lower()
+  }
+
+
+def main():
+  options = ParseArgs()
+  main_manifest = file(options.main_manifest).read()
+  split_manifest = Build(
+      main_manifest,
+      options.split,
+      options.has_code)
+
+  with file(options.out_manifest, 'w') as f:
+    f.write(split_manifest)
+
+  if options.depfile:
+    build_utils.WriteDepfile(
+        options.depfile,
+        [main_manifest] + build_utils.GetPythonDependencies())
+
+
+if __name__ == '__main__':
+  main()
diff --git a/build/android/gyp/jar.py b/build/android/gyp/jar.py
index 17f968c..48abf5e 100755
--- a/build/android/gyp/jar.py
+++ b/build/android/gyp/jar.py
@@ -27,16 +27,20 @@
     jar_cmd.append(os.path.abspath(manifest_file))
   jar_cmd.extend(class_files_rel)
 
-  record_path = '%s.md5.stamp' % jar_path
-  md5_check.CallAndRecordIfStale(
-      lambda: build_utils.CheckOutput(jar_cmd, cwd=jar_cwd),
-      record_path=record_path,
-      input_paths=class_files,
-      input_strings=jar_cmd,
-      force=not os.path.exists(jar_path),
-      )
+  with build_utils.TempDir() as temp_dir:
+    empty_file = os.path.join(temp_dir, '.empty')
+    build_utils.Touch(empty_file)
+    jar_cmd.append(os.path.relpath(empty_file, jar_cwd))
+    record_path = '%s.md5.stamp' % jar_path
+    md5_check.CallAndRecordIfStale(
+        lambda: build_utils.CheckOutput(jar_cmd, cwd=jar_cwd),
+        record_path=record_path,
+        input_paths=class_files,
+        input_strings=jar_cmd,
+        force=not os.path.exists(jar_path),
+        )
 
-  build_utils.Touch(jar_path, fail_if_missing=True)
+    build_utils.Touch(jar_path, fail_if_missing=True)
 
 
 def JarDirectory(classes_dir, excluded_classes, jar_path, manifest_file=None):
diff --git a/build/android/gyp/jar_toc.py b/build/android/gyp/jar_toc.py
index 3cafd6e..6d81008 100755
--- a/build/android/gyp/jar_toc.py
+++ b/build/android/gyp/jar_toc.py
@@ -72,8 +72,10 @@
 
 def UpdateToc(jar_path, toc_path):
   classes = GetClassesInZipFile(zipfile.ZipFile(jar_path))
-  javap_output = CallJavap(classpath=jar_path, classes=classes)
-  toc = ExtractToc(javap_output)
+  toc = ''
+  if len(classes) != 0:
+    javap_output = CallJavap(classpath=jar_path, classes=classes)
+    toc = ExtractToc(javap_output)
 
   with open(toc_path, 'w') as tocfile:
     tocfile.write(toc)
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py
index a0fcda8..e36fd43 100755
--- a/build/android/gyp/javac.py
+++ b/build/android/gyp/javac.py
@@ -236,11 +236,12 @@
             break
       java_files = filtered_java_files
 
-    DoJavac(
-        classpath,
-        classes_dir,
-        options.chromium_code,
-        java_files)
+    if len(java_files) != 0:
+      DoJavac(
+          classpath,
+          classes_dir,
+          options.chromium_code,
+          java_files)
 
     if options.jar_path:
       if options.main_class or options.manifest_entry:
diff --git a/build/android/gyp/process_resources.py b/build/android/gyp/process_resources.py
index 7a5fdf8..4914189 100755
--- a/build/android/gyp/process_resources.py
+++ b/build/android/gyp/process_resources.py
@@ -73,6 +73,10 @@
       help='Do not generate v14 resources. Instead, just verify that the '
       'resources are already compatible with v14, i.e. they don\'t use '
       'attributes that cause crashes on certain devices.')
+  parser.add_option(
+      '--v14-skip',
+      action="store_true",
+      help='Do not generate nor verify v14 resources')
 
   parser.add_option(
       '--extra-res-packages',
@@ -319,11 +323,12 @@
 
     input_resource_dirs = build_utils.ParseGypList(options.resource_dirs)
 
-    for resource_dir in input_resource_dirs:
-      generate_v14_compatible_resources.GenerateV14Resources(
-          resource_dir,
-          v14_dir,
-          options.v14_verify_only)
+    if not options.v14_skip:
+      for resource_dir in input_resource_dirs:
+        generate_v14_compatible_resources.GenerateV14Resources(
+            resource_dir,
+            v14_dir,
+            options.v14_verify_only)
 
     dep_zips = build_utils.ParseGypList(options.dependencies_res_zips)
     input_files += dep_zips
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index 0f3bfad..8507a95 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -79,9 +79,32 @@
 
 
 def GetAllDepsConfigsInOrder(deps_config_paths):
-  def Deps(path):
+  def GetDeps(path):
     return set(GetDepConfig(path)['deps_configs'])
-  return build_utils.GetSortedTransitiveDependencies(deps_config_paths, Deps)
+  return build_utils.GetSortedTransitiveDependencies(deps_config_paths, GetDeps)
+
+
+class Deps(object):
+  def __init__(self, direct_deps_config_paths):
+    self.all_deps_config_paths = GetAllDepsConfigsInOrder(
+        direct_deps_config_paths)
+    self.direct_deps_configs = [
+        GetDepConfig(p) for p in direct_deps_config_paths]
+    self.all_deps_configs = [
+        GetDepConfig(p) for p in self.all_deps_config_paths]
+
+  def All(self, wanted_type=None):
+    if type is None:
+      return self.all_deps_configs
+    return DepsOfType(wanted_type, self.all_deps_configs)
+
+  def Direct(self, wanted_type=None):
+    if wanted_type is None:
+      return self.direct_deps_configs
+    return DepsOfType(wanted_type, self.direct_deps_configs)
+
+  def AllConfigPaths(self):
+    return self.all_deps_config_paths
 
 
 def main(argv):
@@ -166,20 +189,23 @@
 
   direct_deps_config_paths = [
       c for c in possible_deps_config_paths if not c in unknown_deps]
-  all_deps_config_paths = GetAllDepsConfigsInOrder(direct_deps_config_paths)
 
-  direct_deps_configs = [GetDepConfig(p) for p in direct_deps_config_paths]
-  all_deps_configs = [GetDepConfig(p) for p in all_deps_config_paths]
+  deps = Deps(direct_deps_config_paths)
+  direct_library_deps = deps.Direct('java_library')
+  all_library_deps = deps.All('java_library')
 
-  direct_library_deps = DepsOfType('java_library', direct_deps_configs)
-  all_library_deps = DepsOfType('java_library', all_deps_configs)
-
-  direct_resources_deps = DepsOfType('android_resources', direct_deps_configs)
-  all_resources_deps = DepsOfType('android_resources', all_deps_configs)
+  direct_resources_deps = deps.Direct('android_resources')
+  all_resources_deps = deps.All('android_resources')
   # Resources should be ordered with the highest-level dependency first so that
   # overrides are done correctly.
   all_resources_deps.reverse()
 
+  if options.type == 'android_apk' and options.tested_apk_config:
+    tested_apk_deps = Deps([options.tested_apk_config])
+    tested_apk_resources_deps = tested_apk_deps.All('android_resources')
+    all_resources_deps = [
+        d for d in all_resources_deps if not d in tested_apk_resources_deps]
+
   # Initialize some common config.
   config = {
     'deps_info': {
@@ -265,10 +291,8 @@
   # An instrumentation test apk should exclude the dex files that are in the apk
   # under test.
   if options.type == 'android_apk' and options.tested_apk_config:
-    tested_apk_config_paths = GetAllDepsConfigsInOrder(
-        [options.tested_apk_config])
-    tested_apk_configs = [GetDepConfig(p) for p in tested_apk_config_paths]
-    tested_apk_library_deps = DepsOfType('java_library', tested_apk_configs)
+    tested_apk_deps = Deps([options.tested_apk_config])
+    tested_apk_library_deps = tested_apk_deps.All('java_library')
     tested_apk_deps_dex_files = [c['dex_path'] for c in tested_apk_library_deps]
     deps_dex_files = [
         p for p in deps_dex_files if not p in tested_apk_deps_dex_files]
@@ -325,7 +349,7 @@
   if options.depfile:
     build_utils.WriteDepfile(
         options.depfile,
-        all_deps_config_paths + build_utils.GetPythonDependencies())
+        deps.AllConfigPaths() + build_utils.GetPythonDependencies())
 
 
 if __name__ == '__main__':
diff --git a/build/android/provision_devices.py b/build/android/provision_devices.py
index b366f0c..259bd55 100755
--- a/build/android/provision_devices.py
+++ b/build/android/provision_devices.py
@@ -50,10 +50,11 @@
 
 
 def ProvisionDevices(options):
-  if options.device is not None:
-    devices = [options.device]
-  else:
-    devices = device_utils.DeviceUtils.HealthyDevices()
+  devices = device_utils.DeviceUtils.HealthyDevices()
+  if options.device:
+    devices = [d for d in devices if d == options.device]
+    if not devices:
+      raise device_errors.DeviceUnreachableError(options.device)
 
   parallel_devices = device_utils.DeviceUtils.parallel(devices)
   parallel_devices.pMap(ProvisionDevice, options)
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
index 1ed1877..f7191f7 100644
--- a/build/android/pylib/android_commands.py
+++ b/build/android/pylib/android_commands.py
@@ -5,7 +5,11 @@
 """Provides an interface to communicate with the device via the adb command.
 
 Assumes adb binary is currently on system path.
+
+Note that this module is deprecated.
 """
+# TODO(jbudorick): Delete this file once no clients use it.
+
 # pylint: skip-file
 
 import collections
diff --git a/build/android/pylib/device/adb_wrapper.py b/build/android/pylib/device/adb_wrapper.py
index 8e8abf8..f88eab3 100644
--- a/build/android/pylib/device/adb_wrapper.py
+++ b/build/android/pylib/device/adb_wrapper.py
@@ -415,6 +415,40 @@
       raise device_errors.AdbCommandFailedError(
           cmd, output, device_serial=self._device_serial)
 
+  def InstallMultiple(self, apk_paths, forward_lock=False, reinstall=False,
+                      sd_card=False, allow_downgrade=False, partial=False,
+                      timeout=60*2, retries=_DEFAULT_RETRIES):
+    """Install an apk with splits on the device.
+
+    Args:
+      apk_paths: Host path to the APK file.
+      forward_lock: (optional) If set forward-locks the app.
+      reinstall: (optional) If set reinstalls the app, keeping its data.
+      sd_card: (optional) If set installs on the SD card.
+      timeout: (optional) Timeout per try in seconds.
+      retries: (optional) Number of retries to attempt.
+      allow_downgrade: (optional) Allow versionCode downgrade.
+      partial: (optional) Package ID if apk_paths doesn't include all .apks.
+    """
+    for path in apk_paths:
+      _VerifyLocalFileExists(path)
+    cmd = ['install-multiple']
+    if forward_lock:
+      cmd.append('-l')
+    if reinstall:
+      cmd.append('-r')
+    if sd_card:
+      cmd.append('-s')
+    if allow_downgrade:
+      cmd.append('-d')
+    if partial:
+      cmd.extend(('-p', partial))
+    cmd.extend(apk_paths)
+    output = self._RunDeviceAdbCmd(cmd, timeout, retries)
+    if 'Success' not in output:
+      raise device_errors.AdbCommandFailedError(
+          cmd, output, device_serial=self._device_serial)
+
   def Uninstall(self, package, keep_data=False, timeout=_DEFAULT_TIMEOUT,
                 retries=_DEFAULT_RETRIES):
     """Remove the app |package| from the device.
@@ -570,4 +604,3 @@
       return self.GetState() == _READY_STATE
     except device_errors.CommandFailedError:
       return False
-
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py
index 6e332c7..76e0f50 100644
--- a/build/android/pylib/gtest/gtest_config.py
+++ b/build/android/pylib/gtest/gtest_config.py
@@ -29,6 +29,7 @@
     'content_unittests',
     'events_unittests',
     'gl_tests',
+    'gl_unittests',
     'gpu_unittests',
     'ipc_tests',
     'media_unittests',
diff --git a/build/android/pylib/perf/perf_control.py b/build/android/pylib/perf/perf_control.py
index b6a0989..f89f397 100644
--- a/build/android/pylib/perf/perf_control.py
+++ b/build/android/pylib/perf/perf_control.py
@@ -6,8 +6,10 @@
 import logging
 
 from pylib import android_commands
+from pylib.device import device_errors
 from pylib.device import device_utils
 
+
 class PerfControl(object):
   """Provides methods for setting the performance mode of a device."""
   _CPU_PATH = '/sys/devices/system/cpu'
@@ -28,7 +30,9 @@
 
   def SetHighPerfMode(self):
     """Sets the highest stable performance mode for the device."""
-    if not self._device.HasRoot():
+    try:
+      self._device.EnableRoot()
+    except device_errors.CommandFailedError:
       message = 'Need root for performance mode. Results may be NOISY!!'
       logging.warning(message)
       # Add an additional warning at exit, such that it's clear that any results
diff --git a/build/android/pylib/perf/test_runner.py b/build/android/pylib/perf/test_runner.py
index 9d1f437..3bee602 100644
--- a/build/android/pylib/perf/test_runner.py
+++ b/build/android/pylib/perf/test_runner.py
@@ -66,11 +66,29 @@
 from pylib.device import device_errors
 
 
+def GetPersistedResult(test_name):
+  file_name = os.path.join(constants.PERF_OUTPUT_DIR, test_name)
+  if not os.path.exists(file_name):
+    logging.error('File not found %s', file_name)
+    return None
+
+  with file(file_name, 'r') as f:
+    return pickle.loads(f.read())
+
+
 def OutputJsonList(json_input, json_output):
   with file(json_input, 'r') as i:
     all_steps = json.load(i)
-  step_values = [{'test': k, 'device_affinity': v['device_affinity']}
-      for k, v in all_steps['steps'].iteritems()]
+
+  step_values = []
+  for k, v in all_steps['steps'].iteritems():
+    data = {'test': k, 'device_affinity': v['device_affinity']}
+
+    persisted_result = GetPersistedResult(k)
+    if persisted_result:
+      data['total_time'] = persisted_result['total_time']
+    step_values.append(data)
+
   with file(json_output, 'w') as o:
     o.write(json.dumps(step_values))
   return 0
@@ -86,13 +104,9 @@
   Returns:
     exit code generated by the test step.
   """
-  file_name = os.path.join(constants.PERF_OUTPUT_DIR, test_name)
-  if not os.path.exists(file_name):
-    logging.error('File not found %s', file_name)
+  persisted_result = GetPersistedResult(test_name)
+  if not persisted_result:
     return 1
-
-  with file(file_name, 'r') as f:
-    persisted_result = pickle.loads(f.read())
   logging.info('*' * 80)
   logging.info('Output from:')
   logging.info(persisted_result['cmd'])
diff --git a/build/android/screenshot.py b/build/android/screenshot.py
index c48a255..097739f 100755
--- a/build/android/screenshot.py
+++ b/build/android/screenshot.py
@@ -74,8 +74,11 @@
     logging.getLogger().setLevel(logging.DEBUG)
 
   devices = device_utils.DeviceUtils.HealthyDevices()
-
-  if not options.device:
+  if options.device:
+    device = next((d for d in devices if d == options.device), None)
+    if not device:
+      raise device_errors.DeviceUnreachableError(options.device)
+  else:
     if len(devices) > 1:
       parser.error('Multiple devices are attached. '
                    'Please specify device serial number with --device.')
@@ -83,8 +86,6 @@
       device = devices[0]
     else:
       raise device_errors.NoDevicesError()
-  else:
-    device = device_utils.DeviceUtils(options.device)
 
   if options.video:
     _CaptureVideo(device, host_file, options)
diff --git a/build/common.gypi b/build/common.gypi
index 5cab295..dfa4163 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -371,11 +371,11 @@
       'configuration_policy%': 1,
 
       # Variable safe_browsing is used to control the build time configuration
-      # for safe browsing feature. Safe browsing can be compiled in 3 different
+      # for safe browsing feature. Safe browsing can be compiled in 4 different
       # levels: 0 disables it, 1 enables it fully, and 2 enables only UI and
-      # reporting features without enabling phishing and malware detection. This
-      # is useful to integrate a third party phishing/malware detection to
-      # existing safe browsing logic.
+      # reporting features for use with Data Saver on Mobile, and 3 enables
+      # extended mobile protection via an external API.  When 3 is fully
+      # deployed, it will replace 2.
       'safe_browsing%': 1,
 
       # Web speech is enabled by default. Set to 0 to disable.
@@ -2174,23 +2174,17 @@
                 ],
               },
               'clang_dynlib_flags%': '-Xclang -load -Xclang <(clang_lib_path) ',
-              'clang_plugin_args%': '',
             }, { # OS == "win"
               # On Windows, the plugin is built directly into clang, so there's
               # no need to load it dynamically.
               'clang_dynlib_flags%': '',
-
-              # Don't error on plugin warnings on Windows until pre-existing warnings
-              # are cleaned up.  https://crbug.com/467287
-              'clang_plugin_args%': '-Xclang -plugin-arg-find-bad-constructs -Xclang warn-only',
             }]
           ],
         },
         # If you change these, also change build/config/clang/BUILD.gn.
         'clang_chrome_plugins_flags%':
           '<(clang_dynlib_flags)'
-          '-Xclang -add-plugin -Xclang find-bad-constructs '
-          '<(clang_plugin_args)',
+          '-Xclang -add-plugin -Xclang find-bad-constructs ',
       }],
       ['asan==1 or msan==1 or lsan==1 or tsan==1', {
         'clang%': 1,
@@ -2934,6 +2928,8 @@
         'defines': ['ENABLE_AUTOFILL_DIALOG=1'],
       }],
       ['enable_prod_wallet_service==1', {
+        # In GN, this is set on the autofill tagets only. See
+        # //components/autofill/core/browser:wallet_service
         'defines': ['ENABLE_PROD_WALLET_SERVICE=1'],
       }],
       ['enable_background==1', {
@@ -3012,8 +3008,8 @@
       # SAFE_BROWSING_DB_REMOTE - service talks via API to a database
       # SAFE_BROWSING_CSD - enable client-side phishing detection.
       ['safe_browsing==1', {
-        # TODO(nparker): Remove existing uses of FULL_SAFE_BROWSING
         'defines': [
+          # TODO(nparker): Remove existing uses of FULL_SAFE_BROWSING
           'FULL_SAFE_BROWSING',
           'SAFE_BROWSING_CSD',
           'SAFE_BROWSING_DB_LOCAL',
@@ -3027,6 +3023,14 @@
           'SAFE_BROWSING_SERVICE',
         ],
       }],
+      ['safe_browsing==3', {
+        'defines': [
+          # TODO(nparker): Remove existing uses of MOBILE_SAFE_BROWSING
+          'MOBILE_SAFE_BROWSING',
+          'SAFE_BROWSING_DB_REMOTE',
+          'SAFE_BROWSING_SERVICE',
+        ],
+      }],
     ],  # conditions for 'target_defaults'
     'target_conditions': [
       ['<(use_libpci)==1', {
@@ -3602,6 +3606,13 @@
         ],
       },
     }],
+    ['os_posix==1 and OS=="linux"', {
+      'defines': [
+        '_LARGEFILE_SOURCE',
+        '_LARGEFILE64_SOURCE',
+        '_FILE_OFFSET_BITS=64',
+      ],
+    }],
     ['os_posix==1 and OS!="mac" and OS!="ios"', {
       'target_defaults': {
         # Enable -Werror by default, but put it in a variable so it can
@@ -3689,12 +3700,6 @@
                   '-fomit-frame-pointer',
                 ],
               }],
-              ['OS!="android"', {
-                'defines': [
-                  '_LARGEFILE_SOURCE',
-                  '_LARGEFILE64_SOURCE',
-                ],
-              }],
               ['OS=="linux" and target_arch=="ia32"', {
                 'ldflags': [
                   '-Wl,--no-as-needed',
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 2427b72..5eb5e0a 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -41,11 +41,8 @@
 #
 # For now we define these globally to match the current GYP build.
 config("feature_flags") {
-  # TODO(brettw) most of these need to be parameterized.
-  defines = [
-    "CHROMIUM_BUILD",
-    "V8_DEPRECATION_WARNINGS",  # Don't use deprecated V8 APIs anywhere.
-  ]
+  # TODO(brettw) this probably needs to be parameterized.
+  defines = [ "V8_DEPRECATION_WARNINGS" ]  # Don't use deprecated V8 APIs anywhere.
 
   if (cld_version > 0) {
     defines += [ "CLD_VERSION=$cld_version" ]
@@ -238,6 +235,18 @@
   } else if (safe_browsing_mode == 2) {
     defines += [ "MOBILE_SAFE_BROWSING" ]
     defines += [ "SAFE_BROWSING_SERVICE" ]
+  } else if (safe_browsing_mode == 3) {
+    defines += [ "MOBILE_SAFE_BROWSING" ]
+    defines += [ "SAFE_BROWSING_DB_REMOTE" ]
+    defines += [ "SAFE_BROWSING_SERVICE" ]
+  }
+  if (is_official_build) {
+    defines += [ "OFFICIAL_BUILD" ]
+  }
+  if (is_chrome_branded) {
+    defines += [ "GOOGLE_CHROME_BUILD" ]
+  } else {
+    defines += [ "CHROMIUM_BUILD" ]
   }
 }
 
@@ -271,6 +280,18 @@
 
 config("release") {
   defines = [ "NDEBUG" ]
+
+  # Sanitizers.
+  # TODO(GYP) The GYP build has "release_valgrind_build == 0" for this
+  # condition. When Valgrind is set up, we need to do the same here.
+  if (!is_tsan) {
+    defines += [ "NVALGRIND" ]
+    if (!is_nacl) {
+      # NaCl always enables dynamic annotations. Currently this value is set to
+      # 1 for all .nexes.
+      defines += [ "DYNAMIC_ANNOTATIONS_ENABLED=0" ]
+    }
+  }
 }
 
 # Default libraries ------------------------------------------------------------
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 2274c0e..ee32088 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -488,11 +488,17 @@
   }
   set_default_toolchain("$host_toolchain")
 } else if (is_android) {
-  # Use clang for the x86/64 Linux host builds.
-  if (host_cpu == "x86" || host_cpu == "x64") {
-    host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
+  if (host_os == "linux") {
+    # Use clang for the x86/64 Linux host builds.
+    if (host_cpu == "x86" || host_cpu == "x64") {
+      host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
+    } else {
+      host_toolchain = "//build/toolchain/linux:$host_cpu"
+    }
+  } else if (host_os == "mac") {
+    host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
   } else {
-    host_toolchain = "//build/toolchain/linux:$host_cpu"
+    assert(false, "Unknown host for android cross compile")
   }
   set_default_toolchain("//build/toolchain/android:$current_cpu")
 } else if (is_linux) {
@@ -507,11 +513,11 @@
     set_default_toolchain("//build/toolchain/cros:target")
   }
 } else if (is_mac) {
-  host_toolchain = "//build/toolchain/mac:clang"
+  host_toolchain = "//build/toolchain/mac:clang_x64"
   set_default_toolchain(host_toolchain)
 } else if (is_ios) {
-  host_toolchain = "//build/toolchain/mac:host_clang"
-  set_default_toolchain("//build/toolchain/mac:clang")
+  host_toolchain = "//build/toolchain/mac:clang_x64"
+  set_default_toolchain("//build/toolchain/mac:clang_$current_cpu")
 } else if (is_nacl) {
   # TODO(GYP): This will need to change when we get NaCl working
   # on multiple platforms, but this whole block of code (how we define
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index 093e8b3..0e25a9a 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -60,6 +60,8 @@
   # architecture, which is different than the names GN uses.
   if (host_os == "linux") {
     android_host_os = "linux"
+  } else if (host_os == "mac") {
+    android_host_os = "darwin"
   } else {
     assert(false, "Need Android toolchain support for your build OS.")
   }
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 2a7a892..07a05e1 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1177,3 +1177,53 @@
     }
   }
 }
+
+# Creates an AndroidManifest.xml for an APK split.
+template("generate_split_manifest") {
+  assert(defined(invoker.main_manifest))
+  assert(defined(invoker.out_manifest))
+  assert(defined(invoker.split_name))
+
+  action(target_name) {
+    depfile = "$target_gen_dir/$target_name.d"
+    args = [
+      "--main-manifest",
+      rebase_path(invoker.main_manifest, root_build_dir),
+      "--out-manifest",
+      rebase_path(invoker.out_manifest, root_build_dir),
+      "--split",
+      invoker.split_name,
+    ]
+    if (defined(invoker.version_code)) {
+      args += [
+        "--version-code",
+        invoker.version_code,
+      ]
+    }
+    if (defined(invoker.version_name)) {
+      args += [
+        "--version-name",
+        invoker.version_name,
+      ]
+    }
+    if (defined(invoker.has_code)) {
+      args += [
+        "--has-code",
+        invoker.has_code,
+      ]
+    }
+    args += [
+      "--depfile",
+      rebase_path(depfile, root_build_dir),
+    ]
+
+    script = "//build/android/gyp/generate_split_manifest.py"
+    outputs = [
+      depfile,
+      invoker.out_manifest,
+    ]
+    inputs = [
+      invoker.main_manifest,
+    ]
+  }
+}
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 168ebb4..0b7593d 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1582,9 +1582,11 @@
       deps += invoker.deps
     }
     datadeps = [
-      "//tools/android/forwarder2",
       "//tools/android/md5sum",
     ]
+    if (host_os == "linux") {
+      datadeps += [ "//tools/android/forwarder2" ]
+    }
     if (defined(invoker.datadeps)) {
       datadeps += invoker.datadeps
     }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 9ebb2e7..0e28e7d 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -336,6 +336,7 @@
         "-fno-unwind-tables",
         "-fno-asynchronous-unwind-tables",
       ]
+      defines += [ "NO_UNWIND_TABLES" ]
     } else {
       cflags += [ "-funwind-tables" ]
     }
@@ -636,6 +637,18 @@
       "__STDC_CONSTANT_MACROS",
       "__STDC_FORMAT_MACROS",
     ]
+
+    if (using_sanitizer) {
+      # _FORTIFY_SOURCE isn't really supported by Clang now, see
+      # http://llvm.org/bugs/show_bug.cgi?id=16821.
+      # It seems to work fine with Ubuntu 12 headers though, so use it in
+      # official builds.
+      #
+      # Non-chromium code is not guaranteed to compile cleanly with
+      # _FORTIFY_SOURCE. Also, fortified build may fail when optimizations are
+      # disabled, so only do that for Release build.
+      defines += [ "_FORTIFY_SOURCE=2" ]
+    }
   }
 }
 config("no_chromium_code") {
diff --git a/build/config/features.gni b/build/config/features.gni
index 3873458..82b7d06 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -51,7 +51,11 @@
   enable_media_router = !is_ios && !is_android
 
   # Enables proprietary codecs and demuxers; e.g. H264, MOV, AAC, and MP3.
-  proprietary_codecs = false
+  # Android OS includes support for proprietary codecs regardless of building
+  # Chromium or Google Chrome. We also ship Google Chrome and Chromecast with
+  # proprietary codecs.
+  # TODO(GYP) The GYP build has || chromecast==1 for this:
+  proprietary_codecs = is_android || is_chrome_branded
 
   enable_configuration_policy = true
 
@@ -85,12 +89,12 @@
   # (e.g. Android and ChromeCast) that use a browser side CDM.
   enable_browser_cdms = is_android
 
-  # Variable safe_browsing is used to control the build time configuration for
-  # safe browsing feature. Safe browsing can be compiled in 3 different levels:
-  # 0 disables it, 1 enables it fully, and 2 enables only UI and reporting
-  # features without enabling phishing and malware detection. This is useful to
-  # integrate a third party phishing/malware detection to existing safe browsing
-  # logic.
+  # Variable safe_browsing is used to control the build time configuration
+  # for safe browsing feature. Safe browsing can be compiled in 4 different
+  # levels: 0 disables it, 1 enables it fully, and 2 enables only UI and
+  # reporting features for use with Data Saver on Mobile, and 3 enables
+  # extended mobile protection via an external API.  When 3 is fully deployed,
+  # it will replace 2.
   if (is_android) {
     safe_browsing_mode = 2
   } else if (is_ios) {
diff --git a/build/config/gcc/BUILD.gn b/build/config/gcc/BUILD.gn
index c6cfe72..40243cd 100644
--- a/build/config/gcc/BUILD.gn
+++ b/build/config/gcc/BUILD.gn
@@ -20,21 +20,22 @@
 
 # Settings for executables and shared libraries.
 config("executable_ldconfig") {
-  ldflags = [
-    # Want to pass "\$". GN will re-escape as required for ninja.
-    "-Wl,-rpath=\$ORIGIN/",
-    "-Wl,-rpath-link=",
-
-    # Newer binutils don't set DT_RPATH unless you disable "new" dtags
-    # and the new DT_RUNPATH doesn't work without --no-as-needed flag.
-    "-Wl,--disable-new-dtags",
-  ]
-
   if (is_android) {
-    ldflags += [
+    ldflags = [
       "-Bdynamic",
       "-Wl,-z,nocopyreloc",
     ]
+  } else {
+    # Android doesn't support rpath.
+    ldflags = [
+      # Want to pass "\$". GN will re-escape as required for ninja.
+      "-Wl,-rpath=\$ORIGIN/",
+      "-Wl,-rpath-link=",
+
+      # Newer binutils don't set DT_RPATH unless you disable "new" dtags
+      # and the new DT_RUNPATH doesn't work without --no-as-needed flag.
+      "-Wl,--disable-new-dtags",
+    ]
   }
 }
 
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index 4257cc0..ab16c05 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -173,7 +173,10 @@
         '../sync/tools/sync_tools.gyp:sync_client',
         '../sync/tools/sync_tools.gyp:sync_listen_notifications',
         '../testing/gmock.gyp:gmock_main',
-        '../third_party/WebKit/public/all.gyp:blink_tests',
+        '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests',
+        '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests',
+        '../third_party/WebKit/Source/web/web_tests.gyp:webkit_unit_tests',
+        '../third_party/WebKit/Source/wtf/wtf_tests.gyp:wtf_unittests',
         '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
         '../third_party/codesighs/codesighs.gyp:codesighs',
         '../third_party/codesighs/codesighs.gyp:maptsvdifftool',
@@ -276,8 +279,6 @@
             '../ui/ozone/ozone.gyp:ozone',
           ],
         }],
-
-
         ['use_x11==1', {
           'dependencies': [
             '../tools/xdisplaycheck/xdisplaycheck.gyp:xdisplaycheck',
@@ -313,6 +314,10 @@
 
             '../content/content_shell_and_tests.gyp:content_shell_apk',
 
+            '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests_apk',
+            '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests_apk',
+            '../third_party/WebKit/Source/web/web_tests.gyp:webkit_unit_tests_apk',
+            '../third_party/WebKit/Source/wtf/wtf_tests.gyp:wtf_unittests_apk',
             # TODO(GYP): Are these needed, or will they be pulled in automatically?
             #"//third_party/android_tools:android_gcm_java",
             #"//third_party/android_tools:uiautomator_java",
diff --git a/build/java.gypi b/build/java.gypi
index 730fa22..716eb34 100644
--- a/build/java.gypi
+++ b/build/java.gypi
@@ -69,6 +69,7 @@
     'has_java_resources%': 0,
     'res_extra_dirs': [],
     'res_extra_files': [],
+    'res_v14_skip%': 0,
     'res_v14_verify_only%': 0,
     'resource_input_paths': ['>@(res_extra_files)'],
     'intermediate_dir': '<(SHARED_INTERMEDIATE_DIR)/<(_target_name)',
@@ -157,6 +158,9 @@
             'inputs_list_file': '>|(java_resources.<(_target_name).gypcmd >@(resource_input_paths))',
             'process_resources_options': [],
             'conditions': [
+              ['res_v14_skip == 1', {
+                'process_resources_options': ['--v14-skip']
+              }],
               ['res_v14_verify_only == 1', {
                 'process_resources_options': ['--v14-verify-only']
               }],
diff --git a/build/java_apk.gypi b/build/java_apk.gypi
index cece2be..154c16e 100644
--- a/build/java_apk.gypi
+++ b/build/java_apk.gypi
@@ -141,6 +141,7 @@
     'symlink_script_host_path': '<(intermediate_dir)/create_symlinks.sh',
     'symlink_script_device_path': '<(device_intermediate_dir)/create_symlinks.sh',
     'create_standalone_apk%': 1,
+    'res_v14_skip%': 0,
     'res_v14_verify_only%': 0,
     'variables': {
       'variables': {
@@ -607,6 +608,9 @@
             'dependencies_res_zip_paths=': [],
             'additional_res_packages=': [],
           }],
+          ['res_v14_skip == 1', {
+            'process_resources_options+': ['--v14-skip']
+          }],
           ['res_v14_verify_only == 1', {
             'process_resources_options+': ['--v14-verify-only']
           }],
diff --git a/build/linux/system.gyp b/build/linux/system.gyp
index e7cc9dc..476476e 100644
--- a/build/linux/system.gyp
+++ b/build/linux/system.gyp
@@ -692,9 +692,6 @@
         'cflags': [
           '<!@(<(pkg-config) --cflags dbus-1)',
         ],
-        'defines': [
-          'USE_DBUS',
-        ],
       },
       'link_settings': {
         'ldflags': [
diff --git a/build/toolchain/android/BUILD.gn b/build/toolchain/android/BUILD.gn
index 53ad506..f7f47ff 100644
--- a/build/toolchain/android/BUILD.gn
+++ b/build/toolchain/android/BUILD.gn
@@ -49,6 +49,8 @@
     cxx = compiler_prefix + tool_prefix + "g++"
     ar = tool_prefix + "ar"
     ld = cxx
+    readelf = compiler_prefix + tool_prefix + "readelf"
+    nm = compiler_prefix + tool_prefix + "nm"
 
     toolchain_os = "android"
     toolchain_cpu = invoker.toolchain_cpu
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni
index 0192faa..ae9599a 100644
--- a/build/toolchain/gcc_toolchain.gni
+++ b/build/toolchain/gcc_toolchain.gni
@@ -13,6 +13,8 @@
 #  - cxx
 #  - ar
 #  - ld
+#  - readelf
+#  - nm
 # and the following which is used in the toolchain_args
 #  - toolchain_cpu  (What "current_cpu" should be set to when invoking a
 #                    build using this toolchain.)
@@ -40,6 +42,9 @@
     assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value")
     assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value")
     assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value")
+    assert(defined(invoker.readelf),
+           "gcc_toolchain() must specify a \"readelf\" value")
+    assert(defined(invoker.nm), "gcc_toolchain() must specify a \"nm\" value")
     assert(defined(invoker.toolchain_cpu),
            "gcc_toolchain() must specify a \"toolchain_cpu\"")
     assert(defined(invoker.toolchain_os),
@@ -52,6 +57,8 @@
     cxx = invoker.cxx
     ar = invoker.ar
     ld = invoker.ld
+    readelf = invoker.readelf
+    nm = invoker.nm
 
     # Bring these into our scope for string interpolation with default values.
     if (defined(invoker.libs_section_prefix)) {
@@ -138,7 +145,7 @@
       temporary_tocname = sofile + ".tmp"
       link_command =
           "$ld -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile"
-      toc_command = "{ readelf -d $sofile | grep SONAME ; nm -gD -f p $sofile | cut -f1-2 -d' '; } > $temporary_tocname"
+      toc_command = "{ $readelf -d $sofile | grep SONAME ; $nm -gD -f p $sofile | cut -f1-2 -d' '; } > $temporary_tocname"
       replace_command = "if ! cmp -s $temporary_tocname $tocfile; then mv $temporary_tocname $tocfile; fi"
 
       command = "$link_command && $toc_command && $replace_command"
diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn
index 7bcd9d0..15ad5bd 100644
--- a/build/toolchain/linux/BUILD.gn
+++ b/build/toolchain/linux/BUILD.gn
@@ -23,6 +23,8 @@
 
   ar = "arm-linux-gnueabi-ar"
   ld = cxx
+  readelf = "arm-linux-gnueabi-readelf"
+  nm = "arm-linux-gnueabi-nm"
 
   toolchain_cpu = "arm"
   toolchain_os = "linux"
@@ -39,7 +41,8 @@
   }
   cc = "${compiler_prefix}$prefix/clang"
   cxx = "${compiler_prefix}$prefix/clang++"
-
+  readelf = "readelf"
+  nm = "nm"
   ar = "ar"
   ld = cxx
 
@@ -52,6 +55,8 @@
   cc = "${compiler_prefix}gcc"
   cxx = "$compiler_prefix}g++"
 
+  readelf = "readelf"
+  nm = "nm"
   ar = "ar"
   ld = cxx
 
@@ -71,6 +76,8 @@
   cc = "${compiler_prefix}$prefix/clang"
   cxx = "${compiler_prefix}$prefix/clang++"
 
+  readelf = "readelf"
+  nm = "nm"
   ar = "ar"
   ld = cxx
 
@@ -83,6 +90,8 @@
   cc = "${compiler_prefix}gcc"
   cxx = "${compiler_prefix}g++"
 
+  readelf = "readelf"
+  nm = "nm"
   ar = "ar"
   ld = cxx
 
@@ -96,6 +105,8 @@
   cxx = "mipsel-linux-gnu-g++"
   ar = "mipsel-linux-gnu-ar"
   ld = cxx
+  readelf = "mipsel-linux-gnu-readelf"
+  nm = "mipsel-linux-gnu-nm"
 
   toolchain_cpu = "mipsel"
   toolchain_os = "linux"
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index a4b8651..da4ca05 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -8,8 +8,7 @@
 
 import("../goma.gni")
 
-# Should only be running on Mac.
-assert(is_mac || is_ios)
+assert(host_os == "mac")
 
 import("//build/toolchain/clang.gni")
 import("//build/toolchain/goma.gni")
@@ -20,19 +19,6 @@
   goma_prefix = ""
 }
 
-if (is_clang) {
-  cc = rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang",
-                   root_build_dir)
-  cxx = rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang++",
-                    root_build_dir)
-} else {
-  cc = "gcc"
-  cxx = "g++"
-}
-cc = goma_prefix + cc
-cxx = goma_prefix + cxx
-ld = cxx
-
 # This will copy the gyp-mac-tool to the build directory. We pass in the source
 # file of the win tool.
 gyp_mac_tool_source =
@@ -41,16 +27,15 @@
 
 # Shared toolchain definition. Invocations should set toolchain_os to set the
 # build args in this definition.
-template("mac_clang_toolchain") {
+template("mac_toolchain") {
   toolchain(target_name) {
-    assert(defined(invoker.cc),
-           "mac_clang_toolchain() must specify a \"cc\" value")
-    assert(defined(invoker.cxx),
-           "mac_clang_toolchain() must specify a \"cxx\" value")
-    assert(defined(invoker.ld),
-           "mac_clang_toolchain() must specify a \"ld\" value")
+    assert(defined(invoker.cc), "mac_toolchain() must specify a \"cc\" value")
+    assert(defined(invoker.cxx), "mac_toolchain() must specify a \"cxx\" value")
+    assert(defined(invoker.ld), "mac_toolchain() must specify a \"ld\" value")
+    assert(defined(invoker.toolchain_cpu),
+           "mac_toolchain() must specify a \"toolchain_cpu\"")
     assert(defined(invoker.toolchain_os),
-           "mac_clang_toolchain() must specify a \"toolchain_os\"")
+           "mac_toolchain() must specify a \"toolchain_os\"")
 
     # We can't do string interpolation ($ in strings) on things with dots in
     # them. To allow us to use $cc below, for example, we create copies of
@@ -194,18 +179,56 @@
     }
 
     toolchain_args() {
+      current_cpu = invoker.toolchain_cpu
       current_os = invoker.toolchain_os
+
+      # These values need to be passed through unchanged.
+      target_os = target_os
+      target_cpu = target_cpu
+
+      if (defined(invoker.is_clang)) {
+        is_clang = invoker.is_clang
+      }
     }
   }
 }
 
-# Toolchain representing the target build (either mac or iOS).
-mac_clang_toolchain("clang") {
-  toolchain_os = current_os
+mac_toolchain("clang_arm") {
+  toolchain_cpu = "arm"
+  toolchain_os = "mac"
+  prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+                       root_build_dir)
+  cc = "${goma_prefix}$prefix/clang"
+  cxx = "${goma_prefix}$prefix/clang++"
+  ld = cxx
+  is_clang = true
 }
 
-# This toolchain provides a way for iOS target compiles to reference targets
-# compiled for the host system. It just overrides the OS back to "mac".
-mac_clang_toolchain("host_clang") {
+mac_toolchain("arm") {
+  toolchain_cpu = "arm"
   toolchain_os = "mac"
+  cc = "${goma_prefix}/gcc"
+  cxx = "${goma_prefix}/g++"
+  ld = cxx
+  is_clang = false
+}
+
+mac_toolchain("clang_x64") {
+  toolchain_cpu = "x64"
+  toolchain_os = "mac"
+  prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+                       root_build_dir)
+  cc = "${goma_prefix}$prefix/clang"
+  cxx = "${goma_prefix}$prefix/clang++"
+  ld = cxx
+  is_clang = true
+}
+
+mac_toolchain("x64") {
+  toolchain_cpu = "x64"
+  toolchain_os = "mac"
+  cc = "${goma_prefix}/gcc"
+  cxx = "${goma_prefix}/g++"
+  ld = cxx
+  is_clang = false
 }
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
new file mode 100644
index 0000000..58820c7
--- /dev/null
+++ b/build/util/LASTCHANGE
@@ -0,0 +1 @@
+LASTCHANGE=e8280f3afe7cff09bb5b23c959928ccbdc16da25-refs/heads/master@{#329263}
diff --git a/build/util/LASTCHANGE.blink b/build/util/LASTCHANGE.blink
new file mode 100644
index 0000000..ed95b02
--- /dev/null
+++ b/build/util/LASTCHANGE.blink
@@ -0,0 +1 @@
+LASTCHANGE=195119
diff --git a/sandbox/linux/BUILD.gn b/sandbox/linux/BUILD.gn
index 8496685..6cca0d3 100644
--- a/sandbox/linux/BUILD.gn
+++ b/sandbox/linux/BUILD.gn
@@ -10,8 +10,8 @@
 
   compile_credentials = is_linux
 
-  compile_seccomp_bpf_demo =
-      is_linux && (current_cpu == "x86" || current_cpu == "x64")
+  # On Android, use plain GTest.
+  use_base_test_suite = is_linux
 }
 
 # We have two principal targets: sandbox and sandbox_linux_unittests
@@ -61,6 +61,11 @@
     ]
     deps += [ ":seccomp_bpf" ]
   }
+
+  if (use_base_test_suite) {
+    deps += [ "//base/test:test_support" ]
+    defines = [ "SANDBOX_USES_BASE_TEST_SUITE" ]
+  }
 }
 
 # Sources shared by sandbox_linux_unittests and sandbox_linux_jni_unittests.
@@ -88,10 +93,14 @@
     ":sandbox",
     ":sandbox_linux_test_utils",
     "//base",
-    "//base/test:test_support",
     "//testing/gtest",
   ]
 
+  if (use_base_test_suite) {
+    deps += [ "//base/test:test_support" ]
+    defines = [ "SANDBOX_USES_BASE_TEST_SUITE" ]
+  }
+
   if (is_linux) {
     # Don't use this on Android.
     libs = [ "rt" ]
@@ -124,10 +133,14 @@
     sources += [
       "integration_tests/namespace_unix_domain_socket_unittest.cc",
       "services/credentials_unittest.cc",
-      "services/namespace_sandbox_unittest.cc",
       "services/namespace_utils_unittest.cc",
     ]
 
+    if (use_base_test_suite) {
+      # Tests that use advanced features not available in stock GTest.
+      sources += [ "services/namespace_sandbox_unittest.cc" ]
+    }
+
     # For credentials_unittest.cc
     configs += [ "//build/config/linux:libcap" ]
   }
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 7724223..e09ba39 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -8,9 +8,11 @@
       ['OS=="linux"', {
         'compile_suid_client': 1,
         'compile_credentials': 1,
+        'use_base_test_suite': 1,
       }, {
         'compile_suid_client': 0,
         'compile_credentials': 0,
+        'use_base_test_suite': 0,
       }],
       ['OS=="linux" and (target_arch=="ia32" or target_arch=="x64" or '
          'target_arch=="mipsel")', {
@@ -88,6 +90,14 @@
             'seccomp_bpf',
           ]
         }],
+        [ 'use_base_test_suite==1', {
+          'dependencies': [
+            '../base/base.gyp:test_support_base',
+          ],
+          'defines': [
+            'SANDBOX_USES_BASE_TEST_SUITE',
+          ],
+        }],
       ],
     },
     {
diff --git a/sandbox/linux/sandbox_linux_test_sources.gypi b/sandbox/linux/sandbox_linux_test_sources.gypi
index ce7817d..82d7532 100644
--- a/sandbox/linux/sandbox_linux_test_sources.gypi
+++ b/sandbox/linux/sandbox_linux_test_sources.gypi
@@ -10,7 +10,6 @@
     'sandbox_linux_test_utils',
     'sandbox_services',
     '../base/base.gyp:base',
-    '../base/base.gyp:test_support_base',
     '../testing/gtest.gyp:gtest',
   ],
   'include_dirs': [
@@ -60,12 +59,26 @@
       'sources': [
         'integration_tests/namespace_unix_domain_socket_unittest.cc',
         'services/credentials_unittest.cc',
-        'services/namespace_sandbox_unittest.cc',
         'services/namespace_utils_unittest.cc',
       ],
       'dependencies': [
         '../build/linux/system.gyp:libcap'
       ],
+      'conditions': [
+        [ 'use_base_test_suite==1', {
+          'sources': [
+            'services/namespace_sandbox_unittest.cc',
+          ]
+        }]
+      ],
+    }],
+    [ 'use_base_test_suite==1', {
+      'dependencies': [
+        '../base/base.gyp:test_support_base',
+      ],
+      'defines': [
+        'SANDBOX_USES_BASE_TEST_SUITE',
+      ],
     }],
   ],
 }
diff --git a/sandbox/linux/system_headers/arm_linux_syscalls.h b/sandbox/linux/system_headers/arm_linux_syscalls.h
index bfd5342..1addd53 100644
--- a/sandbox/linux/system_headers/arm_linux_syscalls.h
+++ b/sandbox/linux/system_headers/arm_linux_syscalls.h
@@ -1205,6 +1205,10 @@
 #define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
 #endif
 
+#if !defined(__NR_sync_file_range2)
+#define __NR_sync_file_range2 (__NR_SYSCALL_BASE+341)
+#endif
+
 #if !defined(__NR_tee)
 #define __NR_tee (__NR_SYSCALL_BASE+342)
 #endif
diff --git a/sandbox/linux/tests/main.cc b/sandbox/linux/tests/main.cc
index 687c8bb..caeddee 100644
--- a/sandbox/linux/tests/main.cc
+++ b/sandbox/linux/tests/main.cc
@@ -36,7 +36,7 @@
 }  // namespace
 }  // namespace sandbox
 
-#if defined(OS_ANDROID)
+#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
 void UnitTestAssertHandler(const std::string& str) {
   _exit(1);
 }
@@ -44,9 +44,11 @@
 
 int main(int argc, char* argv[]) {
   base::CommandLine::Init(argc, argv);
-  std::string client_func =
-      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-          switches::kTestChildProcess);
+  std::string client_func;
+#if defined(SANDBOX_USES_BASE_TEST_SUITE)
+  client_func = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+      switches::kTestChildProcess);
+#endif
   if (!client_func.empty()) {
     base::AtExitManager exit_manager;
     return multi_process_function_list::InvokeChildProcessTest(client_func);
@@ -55,7 +57,7 @@
   base::FilePath orig_cwd;
   CHECK(GetCurrentDirectory(&orig_cwd));
 
-#if defined(OS_ANDROID)
+#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
   // The use of Callbacks requires an AtExitManager.
   base::AtExitManager exit_manager;
   testing::InitGoogleTest(&argc, argv);
@@ -69,7 +71,7 @@
   // additional side effect of getting rid of gtest warnings about fork()
   // safety.
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
-#if defined(OS_ANDROID)
+#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
   int tests_result = RUN_ALL_TESTS();
 #else
   int tests_result = base::RunUnitTestsUsingBaseTestSuite(argc, argv);
diff --git a/sandbox/linux/tests/unit_tests.cc b/sandbox/linux/tests/unit_tests.cc
index 5872e94..cfcec96 100644
--- a/sandbox/linux/tests/unit_tests.cc
+++ b/sandbox/linux/tests/unit_tests.cc
@@ -7,6 +7,8 @@
 #include <signal.h>
 #include <stdio.h>
 #include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
@@ -18,6 +20,11 @@
 #include "build/build_config.h"
 #include "sandbox/linux/tests/unit_tests.h"
 
+// Specifically, PNaCl toolchain does not have this flag.
+#if !defined(POLLRDHUP)
+#define POLLRDHUP 0x2000
+#endif
+
 namespace {
 std::string TestFailedMessage(const std::string& msg) {
   return msg.empty() ? std::string() : "Actual test failure: " + msg;
@@ -67,14 +74,20 @@
 static const int kExpectedValue = 42;
 static const int kIgnoreThisTest = 43;
 static const int kExitWithAssertionFailure = 1;
+#if !defined(OS_NACL_NONSFI)
 static const int kExitForTimeout = 2;
+#endif
 
-#if !defined(OS_ANDROID)
+#if defined(SANDBOX_USES_BASE_TEST_SUITE)
 // This is due to StackDumpSignalHandler() performing _exit(1).
 // TODO(jln): get rid of the collision with kExitWithAssertionFailure.
 const int kExitAfterSIGSEGV = 1;
 #endif
 
+// PNaCl toolchain's signal ABIs are incompatible with Linux's.
+// So, for simplicity, just drop the "timeout" feature from unittest framework
+// with relying on the buildbot's timeout feature.
+#if !defined(OS_NACL_NONSFI)
 static void SigAlrmHandler(int) {
   const char failure_message[] = "Timeout reached!\n";
   // Make sure that we never block here.
@@ -106,6 +119,7 @@
   SANDBOX_ASSERT(alarm(time_in_seconds) == 0);  // There should be no previous
                                                 // alarm.
 }
+#endif  // !defined(OS_NACL_NONSFI)
 
 // Runs a test in a sub-process. This is necessary for most of the code
 // in the BPF sandbox, as it potentially makes global state changes and as
@@ -163,7 +177,9 @@
     // Don't set a timeout if running on Valgrind, since it's generally much
     // slower.
     if (!IsRunningOnValgrind()) {
+#if !defined(OS_NACL_NONSFI)
       SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
+#endif
     }
 
     // Disable core files. They are not very useful for our individual test
@@ -282,10 +298,12 @@
   std::string details(TestFailedMessage(msg));
   const char* expected_msg = static_cast<const char*>(aux);
 
-#if defined(OS_ANDROID)
+#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
   const bool subprocess_got_sigsegv =
       WIFSIGNALED(status) && (SIGSEGV == WTERMSIG(status));
 #else
+  // This hack is required when a signal handler is installed
+  // for SEGV that will _exit(1).
   const bool subprocess_got_sigsegv =
       WIFEXITED(status) && (kExitAfterSIGSEGV == WEXITSTATUS(status));
 #endif
diff --git a/sandbox/mac/BUILD.gn b/sandbox/mac/BUILD.gn
index d74bfcb..13960bf 100644
--- a/sandbox/mac/BUILD.gn
+++ b/sandbox/mac/BUILD.gn
@@ -48,8 +48,6 @@
   sources = [
     "bootstrap_sandbox.cc",
     "bootstrap_sandbox.h",
-    "dispatch_source_mach.cc",
-    "dispatch_source_mach.h",
     "launchd_interception_server.cc",
     "launchd_interception_server.h",
     "mach_message_server.cc",
@@ -85,7 +83,6 @@
 test("sandbox_mac_unittests") {
   sources = [
     "bootstrap_sandbox_unittest.mm",
-    "dispatch_source_mach_unittest.cc",
     "policy_unittest.cc",
     "xpc_message_server_unittest.cc",
   ]
diff --git a/sandbox/mac/mach_message_server.cc b/sandbox/mac/mach_message_server.cc
index 5a73357..7cfcecc 100644
--- a/sandbox/mac/mach_message_server.cc
+++ b/sandbox/mac/mach_message_server.cc
@@ -12,7 +12,6 @@
 #include "base/logging.h"
 #include "base/mac/mach_logging.h"
 #include "base/strings/stringprintf.h"
-#include "sandbox/mac/dispatch_source_mach.h"
 
 namespace sandbox {
 
@@ -69,7 +68,7 @@
   // Set up the dispatch queue to service the bootstrap port.
   std::string label = base::StringPrintf(
       "org.chromium.sandbox.MachMessageServer.%p", demuxer_);
-  dispatch_source_.reset(new DispatchSourceMach(
+  dispatch_source_.reset(new base::DispatchSourceMach(
       label.c_str(), server_port_.get(), ^{ ReceiveMessage(); }));
   dispatch_source_->Resume();
 
diff --git a/sandbox/mac/mach_message_server.h b/sandbox/mac/mach_message_server.h
index 645b691..20a543b 100644
--- a/sandbox/mac/mach_message_server.h
+++ b/sandbox/mac/mach_message_server.h
@@ -7,6 +7,7 @@
 
 #include <mach/mach.h>
 
+#include "base/mac/dispatch_source_mach.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/mac/scoped_mach_vm.h"
 #include "base/memory/scoped_ptr.h"
@@ -14,8 +15,6 @@
 
 namespace sandbox {
 
-class DispatchSourceMach;
-
 // A Mach message server that operates a receive port. Messages are received
 // and then passed to the MessageDemuxer for handling. The Demuxer
 // can use the server class to send a reply, forward the message to a
@@ -62,7 +61,7 @@
   base::mac::ScopedMachVM reply_buffer_;
 
   // MACH_RECV dispatch source that handles the |server_port_|.
-  scoped_ptr<DispatchSourceMach> dispatch_source_;
+  scoped_ptr<base::DispatchSourceMach> dispatch_source_;
 
   // Whether or not ForwardMessage() was called during ReceiveMessage().
   bool did_forward_message_;
diff --git a/sandbox/mac/sandbox_mac.gypi b/sandbox/mac/sandbox_mac.gypi
index a2a616f..d5013f8 100644
--- a/sandbox/mac/sandbox_mac.gypi
+++ b/sandbox/mac/sandbox_mac.gypi
@@ -10,8 +10,6 @@
       'sources': [
         'bootstrap_sandbox.cc',
         'bootstrap_sandbox.h',
-        'dispatch_source_mach.cc',
-        'dispatch_source_mach.h',
         'launchd_interception_server.cc',
         'launchd_interception_server.h',
         'mach_message_server.cc',
@@ -93,7 +91,6 @@
       'type': 'executable',
       'sources': [
         'bootstrap_sandbox_unittest.mm',
-        'dispatch_source_mach_unittest.cc',
         'policy_unittest.cc',
         'xpc_message_server_unittest.cc',
       ],
diff --git a/sandbox/mac/xpc_message_server.cc b/sandbox/mac/xpc_message_server.cc
index 45559dd..1cd5c63 100644
--- a/sandbox/mac/xpc_message_server.cc
+++ b/sandbox/mac/xpc_message_server.cc
@@ -10,7 +10,6 @@
 
 #include "base/mac/mach_logging.h"
 #include "base/strings/stringprintf.h"
-#include "sandbox/mac/dispatch_source_mach.h"
 #include "sandbox/mac/xpc.h"
 
 #if defined(MAC_OS_X_VERSION_10_7) && \
@@ -52,7 +51,7 @@
 
   std::string label = base::StringPrintf(
       "org.chromium.sandbox.XPCMessageServer.%p", demuxer_);
-  dispatch_source_.reset(new DispatchSourceMach(
+  dispatch_source_.reset(new base::DispatchSourceMach(
       label.c_str(), server_port_.get(), ^{ ReceiveMessage(); }));
   dispatch_source_->Resume();
 
diff --git a/sandbox/mac/xpc_message_server.h b/sandbox/mac/xpc_message_server.h
index 2810097..5f5a9fa 100644
--- a/sandbox/mac/xpc_message_server.h
+++ b/sandbox/mac/xpc_message_server.h
@@ -7,6 +7,7 @@
 
 #include <AvailabilityMacros.h>
 
+#include "base/mac/dispatch_source_mach.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/memory/scoped_ptr.h"
 #include "sandbox/mac/message_server.h"
@@ -27,8 +28,6 @@
 
 namespace sandbox {
 
-class DispatchSourceMach;
-
 // An implementation of MessageServer that uses XPC pipes to read and write XPC
 // messages from a Mach port.
 class SANDBOX_EXPORT XPCMessageServer : public MessageServer {
@@ -62,7 +61,7 @@
   base::mac::ScopedMachReceiveRight server_port_;
 
   // MACH_RECV dispatch source that handles the |server_port_|.
-  scoped_ptr<DispatchSourceMach> dispatch_source_;
+  scoped_ptr<base::DispatchSourceMach> dispatch_source_;
 
   // The reply message, if one has been created.
   xpc_object_t reply_message_;
diff --git a/sandbox/sandbox_nacl_nonsfi.gyp b/sandbox/sandbox_nacl_nonsfi.gyp
index 906fc7b..f56ad15 100644
--- a/sandbox/sandbox_nacl_nonsfi.gyp
+++ b/sandbox/sandbox_nacl_nonsfi.gyp
@@ -55,6 +55,29 @@
             '../base/base_nacl.gyp:base_nacl_nonsfi',
           ],
         },
+
+        {
+          'target_name': 'sandbox_linux_test_utils_nacl_nonsfi',
+          'type': 'none',
+          'variables': {
+            'nacl_untrusted_build': 1,
+            'nlib_target': 'libsandbox_linux_test_utils_nacl_nonsfi.a',
+            'build_glibc': 0,
+            'build_newlib': 0,
+            'build_irt': 0,
+            'build_pnacl_newlib': 0,
+            'build_nonsfi_helper': 1,
+
+            'sources': [
+              'linux/seccomp-bpf/sandbox_bpf_test_runner.cc',
+              'linux/tests/sandbox_test_runner.cc',
+              'linux/tests/unit_tests.cc',
+            ],
+          },
+          'dependencies': [
+            '../testing/gtest_nacl.gyp:gtest_nacl',
+          ],
+        },
       ],
     }],
   ],
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc
index 905c5fd..fec98f9 100644
--- a/sandbox/win/src/broker_services.cc
+++ b/sandbox/win/src/broker_services.cc
@@ -410,7 +410,9 @@
   // its |lpValue| parameter persist until |DeleteProcThreadAttributeList| is
   // called; StartupInformation's destructor makes such a call.
   DWORD64 mitigations;
-  HANDLE inherit_handle_list[2];
+
+  std::vector<HANDLE> inherited_handle_list;
+
   base::string16 desktop = policy_base->GetAlternateDesktop();
   if (!desktop.empty()) {
     startup_info.startup_info()->lpDesktop =
@@ -434,18 +436,20 @@
 
     HANDLE stdout_handle = policy_base->GetStdoutHandle();
     HANDLE stderr_handle = policy_base->GetStderrHandle();
-    int inherit_handle_count = 0;
+
     if (stdout_handle != INVALID_HANDLE_VALUE)
-      inherit_handle_list[inherit_handle_count++] = stdout_handle;
+      inherited_handle_list.push_back(stdout_handle);
+
     // Handles in the list must be unique.
     if (stderr_handle != stdout_handle && stderr_handle != INVALID_HANDLE_VALUE)
-      inherit_handle_list[inherit_handle_count++] = stderr_handle;
+      inherited_handle_list.push_back(stderr_handle);
 
-    HandleList handle_list = policy_base->GetHandlesBeingShared();
-    for (auto handle : handle_list)
-      inherit_handle_list[inherit_handle_count++] = handle;
+    HandleList policy_handle_list = policy_base->GetHandlesBeingShared();
 
-    if (inherit_handle_count)
+    for (auto handle : policy_handle_list)
+      inherited_handle_list.push_back(handle);
+
+    if (inherited_handle_list.size())
       ++attribute_count;
 
     if (!startup_info.InitializeProcThreadAttributeList(attribute_count))
@@ -465,11 +469,11 @@
       }
     }
 
-    if (inherit_handle_count) {
+    if (inherited_handle_list.size()) {
       if (!startup_info.UpdateProcThreadAttribute(
               PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
-              inherit_handle_list,
-              sizeof(inherit_handle_list[0]) * inherit_handle_count)) {
+              &inherited_handle_list[0],
+              sizeof(HANDLE) * inherited_handle_list.size())) {
         return SBOX_ERROR_PROC_THREAD_ATTRIBUTES;
       }
       startup_info.startup_info()->dwFlags |= STARTF_USESTDHANDLES;
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 34356e2..02488a6 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -295,6 +295,11 @@
       CopyFile(os.path.join(sanitizer_include_dir, f),
                aux_sanitizer_include_dir)
 
+  if args.run_tests:
+    os.chdir(LLVM_BUILD_DIR)
+    RunCommand(GetVSVersion().SetupScript('x64') +
+               ['&&', 'ninja', 'cr-check-all'])
+
   WriteStampFile(LLVM_WIN_REVISION)
   print 'Clang update was successful.'
   return 0
@@ -329,6 +334,7 @@
   # mad if it sees a flag it doesn't recognize.
   parser.add_argument('--if-needed', action='store_true')
   parser.add_argument('--print-revision', action='store_true')
+  parser.add_argument('--run-tests', action='store_true')
 
   args = parser.parse_args()