Update from https://crrev.com/306706

Includes formatted BUILD.gn files and a buildtools rev new enough to
run gn format ourselves.

Review URL: https://codereview.chromium.org/773373002
diff --git a/DEPS b/DEPS
index 7015978..8bc6c33 100644
--- a/DEPS
+++ b/DEPS
@@ -22,7 +22,7 @@
   'libcxx_revision': '48198f9110397fff47fe7c37cbfa296be7d44d3d',
   'libcxxabi_revision': '4ad1009ab3a59fa7a6896d74d5e4de5885697f95',
   'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
-  'skia_revision': '947556f6583e62b1ae19dcda94e0dea78babda2b',
+  'skia_revision': '96a6c4df417a2382dd183b0dbc1c614819795f2a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and V8 without interference from each other.
@@ -34,7 +34,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
-  'buildtools_revision': 'ded32942a1ebfddff0ba1231898fc4f6c7faacec',
+  'buildtools_revision': 'af2cab762e6de03ee53ba430a596ad98d5006778',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
diff --git a/base/logging.cc b/base/logging.cc
index f3601ee..327ac77 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -19,7 +19,7 @@
 #include <mach-o/dyld.h>
 #elif defined(OS_POSIX)
 #if defined(OS_NACL)
-#include <sys/time.h> // timespec doesn't seem to be in <time.h>
+#include <sys/time.h>  // timespec doesn't seem to be in <time.h>
 #else
 #include <sys/syscall.h>
 #endif
@@ -76,8 +76,7 @@
 const char* const log_severity_names[LOG_NUM_SEVERITIES] = {
   "INFO", "WARNING", "ERROR", "FATAL" };
 
-const char* log_severity_name(int severity)
-{
+const char* log_severity_name(int severity) {
   if (severity >= 0 && severity < LOG_NUM_SEVERITIES)
     return log_severity_names[severity];
   return "UNKNOWN";
@@ -152,7 +151,7 @@
 void DeleteFilePath(const PathString& log_name) {
 #if defined(OS_WIN)
   DeleteFile(log_name.c_str());
-#elif defined (OS_NACL)
+#elif defined(OS_NACL)
   // Do nothing; unlink() isn't supported on NaCl.
 #else
   unlink(log_name.c_str());
@@ -706,8 +705,8 @@
 
 #if defined(OS_WIN)
 BASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code) {
-  const int error_message_buffer_size = 256;
-  char msgbuf[error_message_buffer_size];
+  const int kErrorMessageBufferSize = 256;
+  char msgbuf[kErrorMessageBufferSize];
   DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
   DWORD len = FormatMessageA(flags, NULL, error_code, 0, msgbuf,
                              arraysize(msgbuf), NULL);
@@ -808,5 +807,5 @@
 }  // namespace logging
 
 std::ostream& std::operator<<(std::ostream& out, const wchar_t* wstr) {
-  return out << base::WideToUTF8(std::wstring(wstr));
+  return out << base::WideToUTF8(wstr);
 }
diff --git a/base/process/kill.h b/base/process/kill.h
index de72d7a..f697701 100644
--- a/base/process/kill.h
+++ b/base/process/kill.h
@@ -9,6 +9,7 @@
 #define BASE_PROCESS_KILL_H_
 
 #include "base/files/file_path.h"
+#include "base/process/process.h"
 #include "base/process/process_handle.h"
 #include "base/time/time.h"
 
@@ -146,10 +147,10 @@
 // On Linux this method does not block the calling thread.
 // On OS X this method may block for up to 2 seconds.
 //
-// NOTE: The process handle must have been opened with the PROCESS_TERMINATE
-// and SYNCHRONIZE permissions.
+// NOTE: The process must have been opened with the PROCESS_TERMINATE and
+// SYNCHRONIZE permissions.
 //
-BASE_EXPORT void EnsureProcessTerminated(ProcessHandle process_handle);
+BASE_EXPORT void EnsureProcessTerminated(Process process);
 
 #if defined(OS_POSIX) && !defined(OS_MACOSX)
 // The nicer version of EnsureProcessTerminated() that is patient and will
diff --git a/base/process/kill_mac.cc b/base/process/kill_mac.cc
index 9257ee6..a2632f6 100644
--- a/base/process/kill_mac.cc
+++ b/base/process/kill_mac.cc
@@ -165,8 +165,8 @@
 
 }  // namespace
 
-void EnsureProcessTerminated(ProcessHandle process) {
-  WaitForChildToDie(process, kWaitBeforeKillSeconds);
+void EnsureProcessTerminated(Process process) {
+  WaitForChildToDie(process.pid(), kWaitBeforeKillSeconds);
 }
 
 }  // namespace base
diff --git a/base/process/kill_posix.cc b/base/process/kill_posix.cc
index d17e990..3f304ca 100644
--- a/base/process/kill_posix.cc
+++ b/base/process/kill_posix.cc
@@ -463,13 +463,13 @@
 
 }  // namespace
 
-void EnsureProcessTerminated(ProcessHandle process) {
+void EnsureProcessTerminated(Process process) {
   // If the child is already dead, then there's nothing to do.
-  if (IsChildDead(process))
+  if (IsChildDead(process.pid()))
     return;
 
   const unsigned timeout = 2;  // seconds
-  BackgroundReaper* reaper = new BackgroundReaper(process, timeout);
+  BackgroundReaper* reaper = new BackgroundReaper(process.pid(), timeout);
   PlatformThread::CreateNonJoinable(0, reaper);
 }
 
diff --git a/base/process/kill_win.cc b/base/process/kill_win.cc
index b102a87..0a0c99c 100644
--- a/base/process/kill_win.cc
+++ b/base/process/kill_win.cc
@@ -38,7 +38,7 @@
 
 class TimerExpiredTask : public win::ObjectWatcher::Delegate {
  public:
-  explicit TimerExpiredTask(ProcessHandle process);
+  explicit TimerExpiredTask(Process process);
   ~TimerExpiredTask();
 
   void TimedOut();
@@ -50,24 +50,23 @@
   void KillProcess();
 
   // The process that we are watching.
-  ProcessHandle process_;
+  Process process_;
 
   win::ObjectWatcher watcher_;
 
   DISALLOW_COPY_AND_ASSIGN(TimerExpiredTask);
 };
 
-TimerExpiredTask::TimerExpiredTask(ProcessHandle process) : process_(process) {
-  watcher_.StartWatching(process_, this);
+TimerExpiredTask::TimerExpiredTask(Process process) : process_(process.Pass()) {
+  watcher_.StartWatching(process_.Handle(), this);
 }
 
 TimerExpiredTask::~TimerExpiredTask() {
   TimedOut();
-  DCHECK(!process_) << "Make sure to close the handle.";
 }
 
 void TimerExpiredTask::TimedOut() {
-  if (process_)
+  if (process_.IsValid())
     KillProcess();
 }
 
@@ -76,8 +75,7 @@
   tracked_objects::ScopedTracker tracking_profile(
       FROM_HERE_WITH_EXPLICIT_FUNCTION("TimerExpiredTask_OnObjectSignaled"));
 
-  CloseHandle(process_);
-  process_ = NULL;
+  process_.Close();
 }
 
 void TimerExpiredTask::KillProcess() {
@@ -88,10 +86,10 @@
   // terminates.  We just care that it eventually terminates, and that's what
   // TerminateProcess should do for us. Don't check for the result code since
   // it fails quite often. This should be investigated eventually.
-  base::KillProcess(process_, kProcessKilledExitCode, false);
+  base::KillProcess(process_.Handle(), kProcessKilledExitCode, false);
 
   // Now, just cleanup as if the process exited normally.
-  OnObjectSignaled(process_);
+  OnObjectSignaled(process_.Handle());
 }
 
 }  // namespace
@@ -241,19 +239,18 @@
   return false;
 }
 
-void EnsureProcessTerminated(ProcessHandle process) {
-  DCHECK(process != GetCurrentProcess());
+void EnsureProcessTerminated(Process process) {
+  DCHECK(!process.is_current());
 
   // If already signaled, then we are done!
-  if (WaitForSingleObject(process, 0) == WAIT_OBJECT_0) {
-    CloseHandle(process);
+  if (WaitForSingleObject(process.Handle(), 0) == WAIT_OBJECT_0) {
     return;
   }
 
   MessageLoop::current()->PostDelayedTask(
       FROM_HERE,
       base::Bind(&TimerExpiredTask::TimedOut,
-                 base::Owned(new TimerExpiredTask(process))),
+                 base::Owned(new TimerExpiredTask(process.Pass()))),
       base::TimeDelta::FromMilliseconds(kWaitInterval));
 }
 
diff --git a/base/process/launch.h b/base/process/launch.h
index 06abb29..0450ddf 100644
--- a/base/process/launch.h
+++ b/base/process/launch.h
@@ -22,7 +22,6 @@
 #include "base/posix/file_descriptor_shuffle.h"
 #elif defined(OS_WIN)
 #include <windows.h>
-#include "base/win/scoped_handle.h"
 #endif
 
 namespace base {
@@ -174,9 +173,8 @@
 //
 // Example (including literal quotes)
 //  cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
-BASE_EXPORT bool LaunchProcess(const string16& cmdline,
-                               const LaunchOptions& options,
-                               win::ScopedHandle* process_handle);
+BASE_EXPORT Process LaunchProcess(const string16& cmdline,
+                                  const LaunchOptions& options);
 
 // Launches a process with elevated privileges.  This does not behave exactly
 // like LaunchProcess as it uses ShellExecuteEx instead of CreateProcess to
diff --git a/base/process/launch_win.cc b/base/process/launch_win.cc
index 3c787fe..1d83ef9 100644
--- a/base/process/launch_win.cc
+++ b/base/process/launch_win.cc
@@ -232,6 +232,17 @@
   return true;
 }
 
+// TODO(rvargas) crbug.com/416721: Remove this stub after LaunchProcess is
+// fully migrated to use Process.
+Process LaunchProcess(const string16& cmdline,
+                      const LaunchOptions& options) {
+  win::ScopedHandle process_handle;
+  if (LaunchProcess(cmdline, options, &process_handle))
+    return Process(process_handle.Take());
+
+  return Process();
+}
+
 bool LaunchProcess(const CommandLine& cmdline,
                    const LaunchOptions& options,
                    ProcessHandle* process_handle) {
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc
index c98884d..af88fe1 100644
--- a/base/process/process_util_unittest.cc
+++ b/base/process/process_util_unittest.cc
@@ -888,14 +888,14 @@
 }
 
 TEST_F(ProcessUtilTest, DelayedTermination) {
-  base::ProcessHandle child_process = SpawnChild("process_util_test_never_die");
-  ASSERT_TRUE(child_process);
-  base::EnsureProcessTerminated(child_process);
-  base::WaitForSingleProcess(child_process, base::TimeDelta::FromSeconds(5));
+  base::Process child_process(SpawnChild("process_util_test_never_die"));
+  ASSERT_TRUE(child_process.IsValid());
+  base::EnsureProcessTerminated(child_process.Duplicate());
+  base::WaitForSingleProcess(child_process.Handle(),
+                             base::TimeDelta::FromSeconds(5));
 
   // Check that process was really killed.
-  EXPECT_TRUE(IsProcessDead(child_process));
-  base::CloseProcessHandle(child_process);
+  EXPECT_TRUE(IsProcessDead(child_process.Handle()));
 }
 
 MULTIPROCESS_TEST_MAIN(process_util_test_never_die) {
@@ -906,16 +906,14 @@
 }
 
 TEST_F(ProcessUtilTest, ImmediateTermination) {
-  base::ProcessHandle child_process =
-      SpawnChild("process_util_test_die_immediately");
-  ASSERT_TRUE(child_process);
+  base::Process child_process(SpawnChild("process_util_test_die_immediately"));
+  ASSERT_TRUE(child_process.IsValid());
   // Give it time to die.
   sleep(2);
-  base::EnsureProcessTerminated(child_process);
+  base::EnsureProcessTerminated(child_process.Duplicate());
 
   // Check that process was really killed.
-  EXPECT_TRUE(IsProcessDead(child_process));
-  base::CloseProcessHandle(child_process);
+  EXPECT_TRUE(IsProcessDead(child_process.Handle()));
 }
 
 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) {
diff --git a/build/android/buildbot/bb_device_steps.py b/build/android/buildbot/bb_device_steps.py
index 3ca0f4d..49e6a48 100755
--- a/build/android/buildbot/bb_device_steps.py
+++ b/build/android/buildbot/bb_device_steps.py
@@ -643,8 +643,9 @@
       cmd(options)
 
     if options.install:
-      test_obj = INSTRUMENTATION_TESTS[options.install]
-      InstallApk(options, test_obj, print_step=True)
+      for i in options.install:
+        test_obj = INSTRUMENTATION_TESTS[i]
+        InstallApk(options, test_obj, print_step=True)
 
     if options.test_filter:
       bb_utils.RunSteps(options.test_filter, GetTestStepCmds(), options)
@@ -683,7 +684,7 @@
   parser.add_option('--gtest-filter',
                     help='Filter for running a subset of tests of a gtest test')
   parser.add_option('--asan', action='store_true', help='Run tests with asan.')
-  parser.add_option('--install', metavar='<apk name>',
+  parser.add_option('--install', metavar='<apk name>', action="append",
                     help='Install an apk by name')
   parser.add_option('--no-reboot', action='store_true',
                     help='Do not reboot devices during provisioning.')
diff --git a/build/common.gypi b/build/common.gypi
index f5a3e80..5a8f1b9 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -213,8 +213,8 @@
             'enable_hidpi%': 1,
           }],
 
-          # Enable the OpenSSL backend on Mac OS.
-          ['OS=="mac"', {
+          # Enable the OpenSSL backend on Mac OS and Windows.
+          ['OS=="mac" or OS=="win"', {
             'use_openssl%': 1,
           }],
 
diff --git a/build/config/crypto.gni b/build/config/crypto.gni
index 20004c3..ee23569 100644
--- a/build/config/crypto.gni
+++ b/build/config/crypto.gni
@@ -8,9 +8,10 @@
 # the global build dependency on it should be removed.
 
 declare_args() {
-  # Use OpenSSL instead of NSS. This is used for Android, Mac, and NaCl untrusted
-  # code, and is experimental in other cases (see http://crbug.com/62803).
-  use_openssl = is_android || is_mac || is_nacl
+  # Use OpenSSL instead of NSS. This is used for Android, Mac, NaCl untrusted
+  # code, and Windows, and is experimental in other cases (see
+  # http://crbug.com/62803).
+  use_openssl = is_android || is_mac || is_nacl || is_win
 }
 
 # True when we're using OpenSSL for certificate verification and storage. We
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
index 5b90571..6530866 100644
--- a/cc/resources/picture.cc
+++ b/cc/resources/picture.cc
@@ -175,17 +175,13 @@
     TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::Picture", this);
 }
 
-bool Picture::IsSuitableForGpuRasterization() const {
+bool Picture::IsSuitableForGpuRasterization(const char** reason) const {
   DCHECK(picture_);
 
-  // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext.
-  // Ideally this GrContext should be the same as that for rasterizing this
-  // picture. But we are on the main thread while the rasterization context
-  // may be on the compositor or raster thread.
-  // SkPicture::suitableForGpuRasterization is not implemented yet.
-  // Pass a NULL context for now and discuss with skia folks if the context
-  // is really needed.
-  return picture_->suitableForGpuRasterization(NULL);
+  // TODO(hendrikw): SkPicture::suitableForGpuRasterization takes a GrContext.
+  // Currently the GrContext isn't used, and should probably be removed from
+  // skia.
+  return picture_->suitableForGpuRasterization(nullptr, reason);
 }
 
 int Picture::ApproximateOpCount() const {
diff --git a/cc/resources/picture.h b/cc/resources/picture.h
index 771d715..ec2ff4b 100644
--- a/cc/resources/picture.h
+++ b/cc/resources/picture.h
@@ -65,7 +65,7 @@
   // Has Record() been called yet?
   bool HasRecording() const { return picture_.get() != NULL; }
 
-  bool IsSuitableForGpuRasterization() const;
+  bool IsSuitableForGpuRasterization(const char** reason) const;
   int ApproximateOpCount() const;
   size_t ApproximateMemoryUsage() const;
 
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index d94ce7c..c3050c3 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -556,8 +556,16 @@
       // even if that content is replaced by gpu-friendly content.
       // This is an optimization to avoid iterating though all pictures in
       // the pile after each invalidation.
-      is_suitable_for_gpu_rasterization_ &=
-          picture->IsSuitableForGpuRasterization();
+      if (is_suitable_for_gpu_rasterization_) {
+        const char* reason = nullptr;
+        is_suitable_for_gpu_rasterization_ &=
+            picture->IsSuitableForGpuRasterization(&reason);
+
+        if (!is_suitable_for_gpu_rasterization_) {
+          TRACE_EVENT_INSTANT1("cc", "GPU Rasterization Veto",
+                               TRACE_EVENT_SCOPE_THREAD, "reason", reason);
+        }
+      }
     }
 
     bool found_tile_for_recorded_picture = false;
diff --git a/net/BUILD.gn b/net/BUILD.gn
index a9d20aa..fab7665 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -251,7 +251,7 @@
     }
     if (is_win) {
       sources -= [
-        "cert/cert/sha256_legacy_support_nss_win.cc",
+        "cert/sha256_legacy_support_nss_win.cc",
       ]
     }
   } else {
@@ -500,6 +500,10 @@
     ]
   }
 
+  if (is_ios || is_mac) {
+    sources += gypi_values.net_base_mac_ios_sources
+  }
+
   if (is_android) {
     # Add some Linux sources that were excluded by the filter, but which
     # are needed.
@@ -1150,6 +1154,10 @@
     ]
   }
 
+  if (is_mac || is_ios) {
+    sources += gypi_values.net_base_test_mac_ios_sources
+  }
+
   if (is_chromeos) {
     sources -= [
       "proxy/proxy_config_service_linux_unittest.cc",
diff --git a/net/base/escape.cc b/net/base/escape.cc
index 7a068f8..05cc2b5 100644
--- a/net/base/escape.cc
+++ b/net/base/escape.cc
@@ -318,6 +318,14 @@
   0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
 }};
 
+#if defined(OS_MACOSX)
+// non-printable, non-7bit, and (including space)  "#%<>[\]^`{|}
+static const Charmap kNSURLCharmap = {{
+  0xffffffffL, 0x5000002dL, 0x78000000L, 0xb8000001L,
+  0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
+}};
+#endif  // defined(OS_MACOSX)
+
 // non-printable, non-7bit, and (including space) ?>=<;+'&%$#"![\]^`{|}
 static const Charmap kUrlEscape = {{
   0xffffffffL, 0xf80008fdL, 0x78000001L, 0xb8000001L,
@@ -347,6 +355,12 @@
   return Escape(path, kPathCharmap, false);
 }
 
+#if defined(OS_MACOSX)
+std::string EscapeNSURLPrecursor(const std::string& precursor) {
+  return Escape(precursor, kNSURLCharmap, false, true);
+}
+#endif  // defined(OS_MACOSX)
+
 std::string EscapeUrlEncodedData(const std::string& path, bool use_plus) {
   return Escape(path, kUrlEscape, use_plus);
 }
diff --git a/net/base/escape.h b/net/base/escape.h
index 6c92333..c11df08 100644
--- a/net/base/escape.h
+++ b/net/base/escape.h
@@ -30,6 +30,12 @@
 // encoding the string.  If this conversion fails, we return false.
 NET_EXPORT std::string EscapePath(const std::string& path);
 
+#if defined(OS_MACOSX)
+// Escapes characters as per expectations of NSURL. This includes:
+// non-printable, non-7bit, and (including space)  "#%<>[\]^`{|}
+NET_EXPORT std::string EscapeNSURLPrecursor(const std::string& precursor);
+#endif  // defined(OS_MACOSX)
+
 // Escapes application/x-www-form-urlencoded content.  This includes:
 // non-printable, non-7bit, and (including space)  ?>=<;+'&%$#"![\]^`{|}
 // Space is escaped as + (if use_plus is true) and other special characters
diff --git a/net/base/mac/README b/net/base/mac/README
new file mode 100644
index 0000000..861a358
--- /dev/null
+++ b/net/base/mac/README
@@ -0,0 +1,2 @@
+This directory contains shared code between the Chrome ports to Mac OS X and
+iOS.
diff --git a/net/base/mac/url_conversions.h b/net/base/mac/url_conversions.h
new file mode 100644
index 0000000..56f53a9
--- /dev/null
+++ b/net/base/mac/url_conversions.h
@@ -0,0 +1,27 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_MAC_URL_CONVERSIONS_H_
+#define NET_BASE_MAC_URL_CONVERSIONS_H_
+
+#include "net/base/net_export.h"
+
+class GURL;
+@class NSURL;
+
+namespace net {
+
+// Method for creating a valid NSURL (compliant with RFC 1738/1808/2396) from a
+// valid GURL. This method will return nil if the |url| is not valid.
+// Note that NSURLs should *always* be created from GURLs, so that GURL
+// sanitization rules are applied everywhere.
+NET_EXPORT NSURL* NSURLWithGURL(const GURL& url);
+
+// Method for creating a valid GURL from a NSURL. This method will return an
+// empty GURL if the |url| is nil.
+NET_EXPORT GURL GURLWithNSURL(NSURL* url);
+
+}  // namespace net
+
+#endif  // NET_BASE_MAC_URL_CONVERSIONS_H_
diff --git a/net/base/mac/url_conversions.mm b/net/base/mac/url_conversions.mm
new file mode 100644
index 0000000..3171c6f
--- /dev/null
+++ b/net/base/mac/url_conversions.mm
@@ -0,0 +1,56 @@
+// Copyright 2012 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.
+
+#import "net/base/mac/url_conversions.h"
+
+#import <Foundation/Foundation.h>
+
+#include "base/mac/scoped_nsobject.h"
+#include "net/base/escape.h"
+#include "url/gurl.h"
+#include "url/url_canon.h"
+
+namespace net {
+
+NSURL* NSURLWithGURL(const GURL& url) {
+  if (!url.is_valid())
+    return nil;
+
+  // NSURL strictly enforces RFC 1738 which requires that certain characters
+  // are always encoded. These characters are: "<", ">", """, "#", "%", "{",
+  // "}", "|", "\", "^", "~", "[", "]", and "`".
+  //
+  // GURL leaves some of these characters unencoded in the path, query, and
+  // ref. This function manually encodes those components, and then passes the
+  // result to NSURL.
+  GURL::Replacements replacements;
+  std::string escaped_path = EscapeNSURLPrecursor(url.path());
+  std::string escaped_query = EscapeNSURLPrecursor(url.query());
+  std::string escaped_ref = EscapeNSURLPrecursor(url.ref());
+  if (!escaped_path.empty()) {
+    replacements.SetPath(escaped_path.c_str(),
+                         url::Component(0, escaped_path.size()));
+  }
+  if (!escaped_query.empty()) {
+    replacements.SetQuery(escaped_query.c_str(),
+                          url::Component(0, escaped_query.size()));
+  }
+  if (!escaped_ref.empty()) {
+    replacements.SetRef(escaped_ref.c_str(),
+                        url::Component(0, escaped_ref.size()));
+  }
+  GURL escaped_url = url.ReplaceComponents(replacements);
+
+  base::scoped_nsobject<NSString> escaped_url_string(
+      [[NSString alloc] initWithUTF8String:escaped_url.spec().c_str()]);
+  return [NSURL URLWithString:escaped_url_string];
+}
+
+GURL GURLWithNSURL(NSURL* url) {
+  if (url)
+    return GURL([[url absoluteString] UTF8String]);
+  return GURL();
+}
+
+}  // namespace net
diff --git a/net/base/mac/url_conversions_unittest.mm b/net/base/mac/url_conversions_unittest.mm
new file mode 100644
index 0000000..b8d8f7f
--- /dev/null
+++ b/net/base/mac/url_conversions_unittest.mm
@@ -0,0 +1,229 @@
+// Copyright 2012 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.
+
+#import <Foundation/Foundation.h>
+
+#include "base/mac/scoped_nsobject.h"
+#include "base/strings/sys_string_conversions.h"
+#import "net/base/mac/url_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+#include "url/gurl.h"
+
+namespace {
+
+class URLConversionTest : public ::testing::Test {
+ protected:
+  virtual void SetUp() {
+    testData_.reset([[NSArray alloc]
+        initWithObjects:
+            // Simple URL with protocol
+            @"https://www.google.com/", @"https://www.google.com/",
+
+            // Simple URL with protocol and query string
+            @"https://www.google.com/search?q=gtest",
+            @"https://www.google.com/search?q=gtest",
+
+            // Simple URL with protocol and query string multiple params
+            @"https://www.google.com/search?hl=en&q=gtest",
+            @"https://www.google.com/search?hl=en&q=gtest",
+
+            // Simple URL with protocol and query string and fragment
+            @"https://www.google.com/search?q=gtest#123",
+            @"https://www.google.com/search?q=gtest#123",
+
+            // URL with ~
+            @"http://www.mysite.com/~user", @"http://www.mysite.com/~user",
+
+            // URL with #
+            @"http://www.mysite.com/#123456", @"http://www.mysite.com/#123456",
+
+            // URL with # before ?
+            @"http://www.mysite.com/test#test?test",
+            @"http://www.mysite.com/test#test?test",
+
+            // URL with ? before #
+            @"http://www.mysite.com/test?test#test",
+            @"http://www.mysite.com/test?test#test",
+
+            // URL with two #s
+            @"http://www.mysite.com/test#test#test",
+            @"http://www.mysite.com/test#test%23test",
+
+            // URL with two ?s
+            @"http://www.mysite.com/test?test?test",
+            @"http://www.mysite.com/test?test?test",
+
+            // URL with pattern ? # ?
+            @"http://www.mysite.com/test?test#test?test",
+            @"http://www.mysite.com/test?test#test?test",
+
+            // URL with pattern # ? #
+            @"http://www.mysite.com/test#test?test#test",
+            @"http://www.mysite.com/test#test?test%23test",
+
+            // URL with %
+            @"http://www.mysite.com/%123", @"http://www.mysite.com/%123",
+
+            // URL with [
+            @"http://www.mysite.com/[123", @"http://www.mysite.com/%5B123",
+
+            // URL with ]
+            @"http://www.mysite.com/]123", @"http://www.mysite.com/%5D123",
+
+            // URL with `
+            @"http://www.mysite.com/`123", @"http://www.mysite.com/%60123",
+
+            // URL with ^
+            @"http://www.mysite.com/^123", @"http://www.mysite.com/%5E123",
+
+            // URL with backslash (GURL canonicallizes unescaped \ to /)
+            @"http://www.mysite.com/\\123", @"http://www.mysite.com//123",
+
+            // URL with space
+            @"http://www.mysite.com/~user name",
+            @"http://www.mysite.com/~user%20name",
+
+            // URL with <
+            @"http://www.mysite.com/123<456",
+            @"http://www.mysite.com/123%3C456",
+
+            // URL with >
+            @"http://www.mysite.com/456>123",
+            @"http://www.mysite.com/456%3E123",
+
+            // URL with |
+            @"http://www.mysite.com/|123", @"http://www.mysite.com/%7C123",
+
+            // URL with !
+            @"http://www.mysite.com/!123", @"http://www.mysite.com/!123",
+
+            // URL with ~
+            @"http://www.mysite.com/~user", @"http://www.mysite.com/~user",
+
+            // URL with & (no ?)
+            @"http://www.mysite.com/&123", @"http://www.mysite.com/&123",
+
+            // URL with '
+            @"http://www.mysite.com/'user", @"http://www.mysite.com/'user",
+
+            // URL with "
+            @"http://www.mysite.com/\"user", @"http://www.mysite.com/%22user",
+
+            // URL with (
+            @"http://www.mysite.com/(123", @"http://www.mysite.com/(123",
+
+            // URL with )
+            @"http://www.mysite.com/)123", @"http://www.mysite.com/)123",
+
+            // URL with +
+            @"http://www.mysite.com/+123", @"http://www.mysite.com/+123",
+
+            // URL with *
+            @"http://www.mysite.com/*123", @"http://www.mysite.com/*123",
+
+            // URL with space
+            @"http://www.mysite.com/user name",
+            @"http://www.mysite.com/user%20name",
+
+            // URL with unescaped European accented characters
+            @"http://fr.news.yahoo.com/bactérie-e-coli-ajouter-vinaigre-leau-"
+             "rinçage-légumes-061425535.html",
+            @"http://fr.news.yahoo.com/bact%C3%A9rie-e-coli-ajouter-vinaigre-"
+             "leau-rin%C3%A7age-l%C3%A9gumes-061425535.html",
+
+            // URL with mix of unescaped European accented characters
+            @"http://fr.news.yahoo.com/bactérie-e-coli-ajouter-vinaigre-leau-"
+             "rinçage-l%C3%A9gumes-061425535.html",
+            @"http://fr.news.yahoo.com/bact%C3%A9rie-e-coli-ajouter-vinaigre-"
+             "leau-rin%C3%A7age-l%C3%A9gumes-061425535.html",
+
+            // URL with unescaped Asian unicode characters
+            @"http://www.baidu.com/s?cl=3&fr=tb01000&wd=鍜嬩箞鍠傞",
+            @"http://www.baidu.com/s?cl=3&fr=tb01000&wd="
+             "%E9%8D%9C%E5%AC%A9%E7%AE%9E%E9%8D%A0%E5%82%9E",
+
+            // URL containing every character in the range 20->7F
+            @"http://google.com/ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM"
+             "NOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",
+            @"http://google.com/%20!%22#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCD"
+             "EFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz"
+             "%7B%7C%7D~",
+
+            // URL containing every accented character from the range 80->FF
+            @"http://google.com/¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìí"
+             "îïðñòóôõö÷øùúûüýþÿ",
+            @"http://google.com/%C2%BF%C3%80%C3%81%C3%82%C3%83%C3%84%C3%85%C3"
+             "%86%C3%87%C3%88%C3%89%C3%8A%C3%8B%C3%8C%C3%8D%C3%8E%C3%8F%C3%90"
+             "%C3%91%C3%92%C3%93%C3%94%C3%95%C3%96%C3%97%C3%98%C3%99%C3%9A%C3"
+             "%9B%C3%9C%C3%9D%C3%9E%C3%9F%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5"
+             "%C3%A6%C3%A7%C3%A8%C3%A9%C3%AA%C3%AB%C3%AC%C3%AD%C3%AE%C3%AF%C3"
+             "%B0%C3%B1%C3%B2%C3%B3%C3%B4%C3%B5%C3%B6%C3%B7%C3%B8%C3%B9%C3%BA"
+             "%C3%BB%C3%BC%C3%BD%C3%BE%C3%BF",
+
+            // URL containing every character in the range 20->7F repeated twice
+            @"http://google.com/ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM"
+             "NOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !\"#$%&'()*+,-"
+             "./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
+             "nopqrstuvwxyz{|}~",
+            @"http://google.com/%20!%22#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCD"
+             "EFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz"
+             "%7B%7C%7D~%20!%22%23$%25&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJ"
+             "KLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C"
+             "%7D~",
+
+            // Special case 7F. the weird out of place control character for DEL
+            @"data:,\177", @"data:,%7F",
+
+            // URL with some common control characters.
+            // GURL simply removes most control characters.
+            @"data:,\a\b\t\r\n", @"data:,",
+
+            // All control characters but \000.
+            @"data:,\001\002\003\004\005\006\007\010\011\012\013\014\015\016"
+             "\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036"
+             "\037",
+            @"data:,",
+
+            // Square brackets shouldn't be escaped in IPv6 literal.
+            @"http://[::1]/path/", @"http://[::1]/path/",
+
+            // Test all possible features of a URL.
+            @"http://foobar:nicate@example.com:8080/some/path/"
+             "file.html;params-here?foo=bar#baz",
+            @"http://foobar:nicate@example.com:8080/some/path/"
+             "file.html;params-here?foo=bar#baz",
+
+            // Test a username and password that require escaping.
+            @"http://john!<]:bar[@foo.com/path",
+            @"http://john!%3C%5D:bar%5B@foo.com/path",
+
+            nil]);
+  }
+
+  // NSArray of NSString pairs used for running the tests.
+  // Each pair is in the form <input value, expected result>.
+  base::scoped_nsobject<NSArray> testData_;
+};
+
+TEST_F(URLConversionTest, TestNSURLCreationFromStrings) {
+  for (NSUInteger i = 0; i < [testData_ count]; i += 2) {
+    NSString* inputStr = [testData_ objectAtIndex:i];
+    NSString* expected = [testData_ objectAtIndex:(i + 1)];
+    NSURL* url = net::NSURLWithGURL(GURL(base::SysNSStringToUTF8(inputStr)));
+    EXPECT_NSEQ(expected, [url absoluteString]);
+  }
+}
+
+TEST_F(URLConversionTest, TestURLWithStringDoesNotModifyAlreadyEscapedURLs) {
+  for (NSUInteger i = 0; i < [testData_ count]; i += 2) {
+    NSString* inputStr = [testData_ objectAtIndex:i + 1];
+    NSURL* url = net::NSURLWithGURL(GURL(base::SysNSStringToUTF8(inputStr)));
+    NSString* expected = [testData_ objectAtIndex:i + 1];
+    // Test the expected URL is created.
+    EXPECT_NSEQ(expected, [url absoluteString]);
+  }
+}
+
+}  // anonymous namespace
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc
index 49c4661..5c31137 100644
--- a/net/base/mime_util_unittest.cc
+++ b/net/base/mime_util_unittest.cc
@@ -294,7 +294,7 @@
   std::string nonAscii("application/nonutf8");
   EXPECT_TRUE(ParseMimeTypeWithoutParameter(nonAscii, NULL, NULL));
 #if defined(OS_WIN)
-  nonAscii.append(base::WideToUTF8(std::wstring(L"\u2603")));
+  nonAscii.append(base::WideToUTF8(L"\u2603"));
 #else
   nonAscii.append("\u2603");  // unicode snowman
 #endif
diff --git a/net/http/disk_cache_based_quic_server_info.cc b/net/http/disk_cache_based_quic_server_info.cc
index ab34bbe..fd3a6fa 100644
--- a/net/http/disk_cache_based_quic_server_info.cc
+++ b/net/http/disk_cache_based_quic_server_info.cc
@@ -138,6 +138,11 @@
 }
 
 void DiskCacheBasedQuicServerInfo::PersistInternal() {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::PersistInternal"));
+
   DCHECK(CalledOnValidThread());
   DCHECK_NE(GET_BACKEND, state_);
   DCHECK(new_data_.empty());
@@ -255,6 +260,11 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoGetBackendComplete(int rv) {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoGetBackendComplete"));
+
   if (rv == OK) {
     backend_ = data_shim_->backend;
     state_ = OPEN;
@@ -266,6 +276,11 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoOpenComplete"));
+
   if (rv == OK) {
     entry_ = data_shim_->entry;
     state_ = READ;
@@ -279,6 +294,11 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoReadComplete"));
+
   if (rv > 0)
     data_.assign(read_buffer_->data(), rv);
   else if (rv < 0)
@@ -289,6 +309,11 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoWriteComplete"));
+
   if (rv < 0)
     RecordQuicServerInfoFailure(WRITE_FAILURE);
   state_ = SET_DONE;
@@ -296,6 +321,11 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete"));
+
   if (rv != OK) {
     RecordQuicServerInfoFailure(CREATE_OR_OPEN_FAILURE);
     state_ = SET_DONE;
@@ -311,16 +341,31 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoGetBackend() {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoGetBackend"));
+
   state_ = GET_BACKEND_COMPLETE;
   return http_cache_->GetBackend(&data_shim_->backend, io_callback_);
 }
 
 int DiskCacheBasedQuicServerInfo::DoOpen() {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoOpen"));
+
   state_ = OPEN_COMPLETE;
   return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_);
 }
 
 int DiskCacheBasedQuicServerInfo::DoRead() {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoRead"));
+
   const int32 size = entry_->GetDataSize(0 /* index */);
   if (!size) {
     state_ = WAIT_FOR_DATA_READY_DONE;
@@ -334,6 +379,11 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoWrite() {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoWrite"));
+
   write_buffer_ = new IOBuffer(new_data_.size());
   memcpy(write_buffer_->data(), new_data_.data(), new_data_.size());
   state_ = WRITE_COMPLETE;
@@ -347,6 +397,11 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoCreateOrOpen() {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoCreateOrOpen"));
+
   state_ = CREATE_OR_OPEN_COMPLETE;
   if (entry_)
     return OK;
@@ -359,6 +414,11 @@
 }
 
 int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone"));
+
   DCHECK(!ready_);
   state_ = NONE;
   ready_ = true;
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 23fb2d1..7139abb 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -441,8 +441,12 @@
 
   // Setting this here allows us to check for the existence of a callback_ to
   // determine if we are still inside Start.
-  if (rv == ERR_IO_PENDING)
-    callback_ = callback;
+  if (rv == ERR_IO_PENDING) {
+    callback_ = tracked_objects::ScopedTracker::TrackCallback(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION(
+            "422516 HttpCache::Transaction::Start"),
+        callback);
+  }
 
   return rv;
 }
@@ -459,8 +463,12 @@
 
   int rv = RestartNetworkRequest();
 
-  if (rv == ERR_IO_PENDING)
-    callback_ = callback;
+  if (rv == ERR_IO_PENDING) {
+    callback_ = tracked_objects::ScopedTracker::TrackCallback(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION(
+            "422516 HttpCache::Transaction::RestartIgnoringLastError"),
+        callback);
+  }
 
   return rv;
 }
@@ -478,8 +486,12 @@
 
   int rv = RestartNetworkRequestWithCertificate(client_cert);
 
-  if (rv == ERR_IO_PENDING)
-    callback_ = callback;
+  if (rv == ERR_IO_PENDING) {
+    callback_ = tracked_objects::ScopedTracker::TrackCallback(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION(
+            "422516 HttpCache::Transaction::RestartWithCertificate"),
+        callback);
+  }
 
   return rv;
 }
@@ -501,8 +513,12 @@
 
   int rv = RestartNetworkRequestWithAuth(credentials);
 
-  if (rv == ERR_IO_PENDING)
-    callback_ = callback;
+  if (rv == ERR_IO_PENDING) {
+    callback_ = tracked_objects::ScopedTracker::TrackCallback(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION(
+            "422516 HttpCache::Transaction::RestartWithAuth"),
+        callback);
+  }
 
   return rv;
 }
@@ -560,7 +576,9 @@
 
   if (rv == ERR_IO_PENDING) {
     DCHECK(callback_.is_null());
-    callback_ = callback;
+    callback_ = tracked_objects::ScopedTracker::TrackCallback(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION("422516 HttpCache::Transaction::Read"),
+        callback);
   }
   return rv;
 }
@@ -699,6 +717,11 @@
 //-----------------------------------------------------------------------------
 
 void HttpCache::Transaction::DoCallback(int rv) {
+  // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+  tracked_objects::ScopedTracker tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422516 HttpCache::Transaction::DoCallback"));
+
   DCHECK(rv != ERR_IO_PENDING);
   DCHECK(!callback_.is_null());
 
diff --git a/net/net.gyp b/net/net.gyp
index 5ddf430..8bfcc7b 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -442,6 +442,12 @@
             },
           },
         ],
+        [ 'OS == "ios" or OS == "mac"', {
+            'sources': [
+              '<@(net_base_mac_ios_sources)',
+            ],
+          },
+        ],
         ['OS=="android" and _toolset=="target" and android_webview_build == 0', {
           'dependencies': [
              'net_java',
@@ -550,6 +556,11 @@
             '<@(net_linux_test_sources)',
           ],
         }],
+        ['OS == "mac" or OS == "ios"', {
+          'sources': [
+            '<@(net_base_test_mac_ios_sources)',
+          ],
+        }],
         ['chromeos==1', {
           'sources!': [
             'proxy/proxy_config_service_linux_unittest.cc',
diff --git a/net/net.gypi b/net/net.gypi
index 89a0503..f9f6d23 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -1757,5 +1757,12 @@
       'tools/quic/test_tools/simple_client.h',
       'tools/quic/test_tools/simple_client.cc',
     ],
+    'net_base_mac_ios_sources': [
+      'base/mac/url_conversions.h',
+      'base/mac/url_conversions.mm',
+    ],
+    'net_base_test_mac_ios_sources': [
+      'base/mac/url_conversions_unittest.mm',
+    ],
   }
 }
diff --git a/net/ssl/openssl_platform_key_win.cc b/net/ssl/openssl_platform_key_win.cc
index 8c9589a..c625bff 100644
--- a/net/ssl/openssl_platform_key_win.cc
+++ b/net/ssl/openssl_platform_key_win.cc
@@ -190,24 +190,19 @@
   return (ex_data->key_length + 7) / 8;
 }
 
-// Signs |in| using |rsa| with PKCS #1 padding. If |hash_nid| is NID_md5_sha1,
-// |in| is a TLS MD5/SHA-1 concatenation and should be signed as-is. Otherwise
-// |in| is a standard hash function and should be prefixed with the
-// corresponding DigestInfo before signing. The signature is written to |out|
-// and its length written to |*out_len|. This function returns true on success
-// and false on failure.
-bool RsaSignPKCS1(const RSA* rsa,
-                  int hash_nid,
+int RsaMethodSign(int hash_nid,
                   const uint8_t* in,
-                  size_t in_len,
+                  unsigned in_len,
                   uint8_t* out,
-                  size_t max_out,
-                  size_t* out_len) {
+                  unsigned* out_len,
+                  const RSA* rsa) {
+  // TODO(davidben): Switch BoringSSL's sign hook to using size_t rather than
+  // unsigned.
   const KeyExData* ex_data = RsaGetExData(rsa);
   if (!ex_data) {
     NOTREACHED();
     OPENSSL_PUT_ERROR(RSA, RSA_sign, ERR_R_INTERNAL_ERROR);
-    return false;
+    return 0;
   }
 
   if (ex_data->key->dwKeySpec == CERT_NCRYPT_KEY_SPEC) {
@@ -230,19 +225,19 @@
         break;
       default:
         OPENSSL_PUT_ERROR(RSA, RSA_sign, RSA_R_UNKNOWN_ALGORITHM_TYPE);
-        return false;
+        return 0;
     }
 
     DWORD signature_len;
     SECURITY_STATUS ncrypt_status = g_cng_functions.Get().ncrypt_sign_hash()(
         ex_data->key->hNCryptKey, &rsa_padding_info, const_cast<PBYTE>(in),
-        in_len, out, max_out, &signature_len, BCRYPT_PAD_PKCS1);
+        in_len, out, RSA_size(rsa), &signature_len, BCRYPT_PAD_PKCS1);
     if (FAILED(ncrypt_status) || signature_len == 0) {
       OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
-      return false;
+      return 0;
     }
     *out_len = signature_len;
-    return true;
+    return 1;
   }
 
   ALG_ID hash_alg;
@@ -264,14 +259,14 @@
       break;
     default:
       OPENSSL_PUT_ERROR(RSA, RSA_sign, RSA_R_UNKNOWN_ALGORITHM_TYPE);
-      return false;
+      return 0;
   }
 
   HCRYPTHASH hash;
   if (!CryptCreateHash(ex_data->key->hCryptProv, hash_alg, 0, 0, &hash)) {
     PLOG(ERROR) << "CreateCreateHash failed";
     OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
-    return false;
+    return 0;
   }
   DWORD hash_len;
   DWORD arg_len = sizeof(hash_len);
@@ -279,43 +274,28 @@
                          &arg_len, 0)) {
     PLOG(ERROR) << "CryptGetHashParam HP_HASHSIZE failed";
     OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
-    return false;
+    return 0;
   }
   if (hash_len != in_len) {
     OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
-    return false;
+    return 0;
   }
   if (!CryptSetHashParam(hash, HP_HASHVAL, const_cast<BYTE*>(in), 0)) {
     PLOG(ERROR) << "CryptSetHashParam HP_HASHVAL failed";
     OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
-    return false;
+    return 0;
   }
-  DWORD signature_len = max_out;
+  DWORD signature_len = RSA_size(rsa);
   if (!CryptSignHash(hash, ex_data->key->dwKeySpec, nullptr, 0, out,
                      &signature_len)) {
     PLOG(ERROR) << "CryptSignHash failed";
     OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
-    return false;
+    return 0;
   }
 
   /* CryptoAPI signs in little-endian, so reverse it. */
   std::reverse(out, out + signature_len);
   *out_len = signature_len;
-  return true;
-}
-
-int RsaMethodSign(int hash_nid,
-                  const uint8_t* in,
-                  unsigned in_len,
-                  uint8_t* out,
-                  unsigned* out_len,
-                  const RSA* rsa) {
-  // TOD(davidben): Switch BoringSSL's sign hook to using size_t rather than
-  // unsigned.
-  size_t len;
-  if (!RsaSignPKCS1(rsa, hash_nid, in, in_len, out, RSA_size(rsa), &len))
-    return 0;
-  *out_len = len;
   return 1;
 }
 
@@ -338,24 +318,9 @@
                      const uint8_t* in,
                      size_t in_len,
                      int padding) {
-  DCHECK_EQ(RSA_PKCS1_PADDING, padding);
-  if (padding != RSA_PKCS1_PADDING) {
-    OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_UNKNOWN_PADDING_TYPE);
-    return 0;
-  }
-
-  // BoringSSL calls only sign_raw, not sign, in pre-TLS-1.2 MD5/SHA1
-  // signatures. This hook is implemented only for that case.
-  //
-  // TODO(davidben): Make client auth in BoringSSL call RSA_sign with
-  // NID_md5_sha1. https://crbug.com/437023
-  if (in_len != MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH) {
-    OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_INVALID_MESSAGE_LENGTH);
-    return 0;
-  }
-  if (!RsaSignPKCS1(rsa, NID_md5_sha1, in, in_len, out, max_out, out_len))
-    return 0;
-  return 1;
+  NOTIMPLEMENTED();
+  OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+  return 0;
 }
 
 int RsaMethodDecrypt(RSA* rsa,
@@ -506,7 +471,7 @@
 
   // Ensure the DER-encoded signature fits in the bounds.
   int len = i2d_ECDSA_SIG(sig.get(), nullptr);
-  if (len < 0 || len > ECDSA_size(ec_key)) {
+  if (len < 0 || static_cast<size_t>(len) > ECDSA_size(ec_key)) {
     OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
     return 0;
   }
diff --git a/sandbox/linux/bpf_dsl/bpf_dsl_more_unittest.cc b/sandbox/linux/bpf_dsl/bpf_dsl_more_unittest.cc
index df5dbd5..d6c88d6 100644
--- a/sandbox/linux/bpf_dsl/bpf_dsl_more_unittest.cc
+++ b/sandbox/linux/bpf_dsl/bpf_dsl_more_unittest.cc
@@ -30,6 +30,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/sys_info.h"
 #include "base/threading/thread.h"
 #include "build/build_config.h"
 #include "sandbox/linux/bpf_dsl/policy.h"
@@ -2253,8 +2254,17 @@
 }
 
 SANDBOX_TEST(SandboxBPF, Tsync) {
-  if (!(SandboxBPF::SupportsSeccompSandbox(
-          SandboxBPF::SeccompLevel::MULTI_THREADED))) {
+  const bool supports_multi_threaded = SandboxBPF::SupportsSeccompSandbox(
+      SandboxBPF::SeccompLevel::MULTI_THREADED);
+// On Chrome OS tsync is mandatory.
+#if defined(OS_CHROMEOS)
+  if (base::SysInfo::IsRunningOnChromeOS()) {
+    BPF_ASSERT_EQ(true, supports_multi_threaded);
+  }
+// else a Chrome OS build not running on a Chrome OS device e.g. Chrome bots.
+// In this case fall through.
+#endif
+  if (!supports_multi_threaded) {
     return;
   }
 
diff --git a/skia/ext/bitmap_platform_device_cairo.cc b/skia/ext/bitmap_platform_device_cairo.cc
index 97fc92a..e9dcf3b 100644
--- a/skia/ext/bitmap_platform_device_cairo.cc
+++ b/skia/ext/bitmap_platform_device_cairo.cc
@@ -127,8 +127,8 @@
   BitmapPlatformDevice* device = Create(width, height, is_opaque, surface);
 
 #ifndef NDEBUG
-  if (device && is_opaque)  // Fill with bright bluish green
-    device->eraseColor(SkColorSetARGB(255, 0, 255, 128));
+    if (device && is_opaque)  // Fill with bright bluish green
+        SkCanvas(device).drawColor(0xFF00FF80);
 #endif
 
   return device;
diff --git a/skia/ext/bitmap_platform_device_mac.cc b/skia/ext/bitmap_platform_device_mac.cc
index 871ca83..53569c8 100644
--- a/skia/ext/bitmap_platform_device_mac.cc
+++ b/skia/ext/bitmap_platform_device_mac.cc
@@ -96,7 +96,8 @@
 BitmapPlatformDevice* BitmapPlatformDevice::Create(CGContextRef context,
                                                    int width,
                                                    int height,
-                                                   bool is_opaque) {
+                                                   bool is_opaque,
+                                                   bool do_clear) {
   if (RasterDeviceTooBigToAllocate(width, height))
     return NULL;
 
@@ -114,6 +115,8 @@
       return NULL;
     data = bitmap.getPixels();
   }
+  if (do_clear)
+    memset(data, 0, bitmap.getSafeSize());
 
   // If we were given data, then don't clobber it!
 #ifndef NDEBUG
@@ -140,15 +143,6 @@
   return rv;
 }
 
-BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
-                                                           int height,
-                                                           bool is_opaque) {
-  BitmapPlatformDevice* device = Create(NULL, width, height, is_opaque);
-  if (!is_opaque)
-    device->clear(0);
-  return device;
-}
-
 BitmapPlatformDevice* BitmapPlatformDevice::CreateWithData(uint8_t* data,
                                                            int width,
                                                            int height,
@@ -157,7 +151,7 @@
   if (data)
     context = CGContextForData(data, width, height);
 
-  BitmapPlatformDevice* rv = Create(context, width, height, is_opaque);
+  BitmapPlatformDevice* rv = Create(context, width, height, is_opaque, false);
 
   // The device object took ownership of the graphics context with its own
   // CGContextRetain call.
@@ -238,19 +232,20 @@
 }
 
 SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
-                                                     const CreateInfo& info) {
-  SkASSERT(info.fInfo.colorType() == kN32_SkColorType);
-  return BitmapPlatformDevice::CreateAndClear(info.fInfo.width(),
-                                              info.fInfo.height(),
-                                              info.fInfo.isOpaque());
+                                                     const CreateInfo& cinfo) {
+  const SkImageInfo& info = cinfo.fInfo;
+  const bool do_clear = !info.isOpaque();
+  SkASSERT(info.colorType() == kN32_SkColorType);
+  return Create(NULL, info.width(), info.height(), info.isOpaque(), do_clear);
 }
 
 // PlatformCanvas impl
 
 SkCanvas* CreatePlatformCanvas(CGContextRef ctx, int width, int height,
                                bool is_opaque, OnFailureType failureType) {
+  const bool do_clear = false;
   skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
-      BitmapPlatformDevice::Create(ctx, width, height, is_opaque));
+      BitmapPlatformDevice::Create(ctx, width, height, is_opaque, do_clear));
   return CreateCanvas(dev, failureType);
 }
 
diff --git a/skia/ext/bitmap_platform_device_mac.h b/skia/ext/bitmap_platform_device_mac.h
index 8921117..33ce214 100644
--- a/skia/ext/bitmap_platform_device_mac.h
+++ b/skia/ext/bitmap_platform_device_mac.h
@@ -35,12 +35,7 @@
   // is not initialized.
   static BitmapPlatformDevice* Create(CGContextRef context,
                                       int width, int height,
-                                      bool is_opaque);
-
-  // Creates a BitmapPlatformDevice instance.  If |is_opaque| is false,
-  // then the bitmap is initialzed to 0.
-  static BitmapPlatformDevice* CreateAndClear(int width, int height,
-                                              bool is_opaque);
+                                      bool is_opaque, bool do_clear = false);
 
   // Creates a context for |data| and calls Create.
   // If |data| is NULL, then the bitmap backing store is not initialized.
diff --git a/skia/ext/bitmap_platform_device_skia.cc b/skia/ext/bitmap_platform_device_skia.cc
index 1dcf13b..d057913 100644
--- a/skia/ext/bitmap_platform_device_skia.cc
+++ b/skia/ext/bitmap_platform_device_skia.cc
@@ -20,15 +20,6 @@
   return NULL;
 }
 
-BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
-                                                           int height,
-                                                           bool is_opaque) {
-  BitmapPlatformDevice* device = Create(width, height, is_opaque);
-  if (!is_opaque)
-    device->clear(0);
-  return device;
-}
-
 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                    bool is_opaque,
                                                    uint8_t* data) {
diff --git a/skia/ext/bitmap_platform_device_skia.h b/skia/ext/bitmap_platform_device_skia.h
index 3b8a28d..dfbee56 100644
--- a/skia/ext/bitmap_platform_device_skia.h
+++ b/skia/ext/bitmap_platform_device_skia.h
@@ -25,11 +25,6 @@
   // The bitmap is not initialized.
   static BitmapPlatformDevice* Create(int width, int height, bool is_opaque);
 
-  // Construct a BitmapPlatformDevice, as above.
-  // If |is_opaque| is false, the bitmap is initialized to 0.
-  static BitmapPlatformDevice* CreateAndClear(int width, int height,
-                                              bool is_opaque);
-
   // This doesn't take ownership of |data|. If |data| is null, the bitmap
   // is not initialized to 0.
   static BitmapPlatformDevice* Create(int width, int height, bool is_opaque,
diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc
index 3901ad5..71bb800 100644
--- a/skia/ext/bitmap_platform_device_win.cc
+++ b/skia/ext/bitmap_platform_device_win.cc
@@ -120,7 +120,8 @@
     int width,
     int height,
     bool is_opaque,
-    HANDLE shared_section) {
+    HANDLE shared_section,
+    bool do_clear) {
 
   void* data;
   HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, shared_section,
@@ -132,6 +133,9 @@
   if (!InstallHBitmapPixels(&bitmap, width, height, is_opaque, data, hbitmap))
     return NULL;
 
+  if (do_clear)
+    bitmap.eraseColor(0);
+
 #ifndef NDEBUG
   // If we were given data, then don't clobber it!
   if (!shared_section && is_opaque)
@@ -148,18 +152,9 @@
 // static
 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                    bool is_opaque) {
-  return Create(width, height, is_opaque, NULL);
-}
-
-// static
-BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
-                                                           int height,
-                                                           bool is_opaque) {
-  BitmapPlatformDevice* device = BitmapPlatformDevice::Create(width, height,
-                                                              is_opaque);
-  if (device && !is_opaque)
-    device->clear(0);
-  return device;
+  const HANDLE shared_section = NULL;
+  const bool do_clear = false;
+  return Create(width, height, is_opaque, shared_section, do_clear);
 }
 
 // The device will own the HBITMAP, which corresponds to also owning the pixel
@@ -271,11 +266,11 @@
 }
 
 SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
-                                                    const CreateInfo& info) {
-  SkASSERT(info.fInfo.colorType() == kN32_SkColorType);
-  return BitmapPlatformDevice::CreateAndClear(info.fInfo.width(),
-                                              info.fInfo.height(),
-                                              info.fInfo.isOpaque());
+                                                    const CreateInfo& cinfo) {
+  const SkImageInfo& info = cinfo.fInfo;
+  const bool do_clear = !info.isOpaque();
+  SkASSERT(info.colorType() == kN32_SkColorType);
+  return Create(info.width(), info.height(), info.isOpaque(), NULL, do_clear);
 }
 
 // PlatformCanvas impl
diff --git a/skia/ext/bitmap_platform_device_win.h b/skia/ext/bitmap_platform_device_win.h
index 92b1408..9e32de9 100644
--- a/skia/ext/bitmap_platform_device_win.h
+++ b/skia/ext/bitmap_platform_device_win.h
@@ -35,17 +35,13 @@
   // for details. If |shared_section| is null, the bitmap backing store is not
   // initialized.
   static BitmapPlatformDevice* Create(int width, int height,
-                                      bool is_opaque, HANDLE shared_section);
+                                      bool is_opaque, HANDLE shared_section,
+                                      bool do_clear = false);
 
   // Create a BitmapPlatformDevice with no shared section. The bitmap is not
   // initialized to 0.
   static BitmapPlatformDevice* Create(int width, int height, bool is_opaque);
 
-  // Creates a BitmapPlatformDevice instance respecting the parameters as above.
-  // If |is_opaque| is false, then the bitmap is initialzed to 0.
-  static BitmapPlatformDevice* CreateAndClear(int width, int height,
-                                              bool is_opaque);
-
   virtual ~BitmapPlatformDevice();
 
   // PlatformDevice overrides
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn
index 88676ad..c0d23f3 100644
--- a/third_party/boringssl/BUILD.gn
+++ b/third_party/boringssl/BUILD.gn
@@ -46,6 +46,7 @@
     "BORINGSSL_IMPLEMENTATION",
     "BORINGSSL_NO_STATIC_INITIALIZER",
   ]
+  deps = []
   if (is_component_build) {
     defines += [ "BORINGSSL_SHARED_LIBRARY" ]
   }