diff --git a/tools/chrome_proxy/webdriver/lite_page.py b/tools/chrome_proxy/webdriver/lite_page.py
index c247792b..5afe2da 100644
--- a/tools/chrome_proxy/webdriver/lite_page.py
+++ b/tools/chrome_proxy/webdriver/lite_page.py
@@ -30,7 +30,9 @@
       test_driver.AddChromeArg('--enable-spdy-proxy-auth')
       test_driver.AddChromeArg('--enable-features=NetworkQualityEstimator'
                                '<NetworkQualityEstimator,'
-                               'Previews,DataReductionProxyDecidesTransform')
+                               'Previews,DataReductionProxyDecidesTransform,'
+                               'NetworkService,'
+                               'DataReductionProxyEnabledWithNetworkService')
       test_driver.AddChromeArg(
           '--force-fieldtrial-params=NetworkQualityEstimator.Enabled:'
           'force_effective_connection_type/2G,'
@@ -43,11 +45,14 @@
       test_driver.LoadURL('http://check.googlezip.net/test.html')
 
       lite_page_responses = 0
+      checked_chrome_proxy_header = False
       for response in test_driver.GetHTTPResponses():
-        # Verify client sends ignore directive on every request for session.
-        self.assertIn('exp=ignore_preview_blacklist',
-          response.request_headers['chrome-proxy'])
-        self.assertEqual('2G', response.request_headers['chrome-proxy-ect'])
+        if response.request_headers:
+          # Verify client sends ignore directive on main frame request.
+          self.assertIn('exp=ignore_preview_blacklist',
+            response.request_headers['chrome-proxy'])
+          self.assertEqual('2G', response.request_headers['chrome-proxy-ect'])
+          checked_chrome_proxy_header = True
         if response.url.endswith('html'):
           self.assertTrue(self.checkLitePageResponse(response))
           lite_page_responses = lite_page_responses + 1
@@ -59,6 +64,7 @@
           # No subresources should accept transforms.
           self.assertNotIn('chrome-proxy-accept-transform',
             response.request_headers)
+      self.assertTrue(checked_chrome_proxy_header)
 
       # Verify that a Lite Page response for the main frame was seen.
       self.assertEqual(1, lite_page_responses)
@@ -286,7 +292,9 @@
       test_driver.AddChromeArg('--enable-spdy-proxy-auth')
       test_driver.AddChromeArg('--enable-features=NetworkQualityEstimator'
                                '<NetworkQualityEstimator,'
-                               'Previews,DataReductionProxyDecidesTransform')
+                               'Previews,DataReductionProxyDecidesTransform,'
+                               'NetworkService,'
+                               'DataReductionProxyEnabledWithNetworkService')
       test_driver.AddChromeArg('--force-fieldtrial-params='
                                'NetworkQualityEstimator.Enabled:'
                                'force_effective_connection_type/Slow2G')
@@ -405,7 +413,9 @@
     with TestDriver() as test_driver:
       test_driver.AddChromeArg('--enable-spdy-proxy-auth')
       test_driver.AddChromeArg('--enable-features=NetworkQualityEstimator'
-                               '<NetworkQualityEstimator')
+                               '<NetworkQualityEstimator,'
+                               'NetworkService,'
+                               'DataReductionProxyEnabledWithNetworkService')
       test_driver.AddChromeArg('--force-fieldtrial-params='
                                'NetworkQualityEstimator.Enabled:'
                                'force_effective_connection_type/2G')
@@ -417,6 +427,8 @@
       test_driver.LoadURL('http://check.googlezip.net/test.html')
 
       for response in test_driver.GetHTTPResponses():
+        if not response.request_headers:
+          continue
         self.assertEqual('2G', response.request_headers['chrome-proxy-ect'])
         if response.url.endswith('html'):
           if ParseFlags().android:
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 10b061f..4e9b284 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -35,7 +35,7 @@
 # Do NOT CHANGE this if you don't know what you're doing -- see
 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
-CLANG_REVISION = '356356'
+CLANG_REVISION = '357316'
 
 use_head_revision = bool(os.environ.get('LLVM_FORCE_HEAD_REVISION', '0')
                          in ('1', 'YES'))
@@ -43,7 +43,7 @@
   CLANG_REVISION = 'HEAD'
 
 # This is incremented when pushing a new build of Clang at the same revision.
-CLANG_SUB_REVISION=3
+CLANG_SUB_REVISION=1
 
 PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
 
diff --git a/tools/metrics/common/pretty_print_xml.py b/tools/metrics/common/pretty_print_xml.py
index 712bbd9..ae97ff7 100644
--- a/tools/metrics/common/pretty_print_xml.py
+++ b/tools/metrics/common/pretty_print_xml.py
@@ -78,6 +78,11 @@
     self.tags_that_allow_single_line = tags_that_allow_single_line
     self.tags_alphabetization_rules = tags_alphabetization_rules
 
+    self.wrapper = textwrap.TextWrapper()
+    self.wrapper.break_on_hyphens = False
+    self.wrapper.break_long_words = False
+    self.wrapper.width = WRAP_COLUMN
+
   def PrettyPrintXml(self, tree):
     tree = self._TransformByAlphabetizing(tree)
     tree = self.PrettyPrintNode(tree)
@@ -158,6 +163,127 @@
       self._TransformByAlphabetizing(c)
     return node
 
+  def _PrettyPrintText(self, node, indent):
+    # Wrap each paragraph in the text to fit in the 80 column limit.
+    self.wrapper.initial_indent = ' ' * indent
+    self.wrapper.subsequent_indent = ' ' * indent
+    text = XmlEscape(node.data)
+    paragraphs = SplitParagraphs(text)
+    # Wrap each paragraph and separate with two newlines.
+    return '\n\n'.join(self.wrapper.fill(p) for p in paragraphs)
+
+  def _PrettyPrintElement(self, node, indent):
+    # Check if tag name is valid.
+    if node.tagName not in self.attribute_order:
+      logging.error('Unrecognized tag "%s"', node.tagName)
+      raise Error('Unrecognized tag "%s"', node.tagName)
+
+    # Newlines.
+    newlines_after_open, newlines_before_close, newlines_after_close = (
+        self.tags_that_have_extra_newline.get(node.tagName, (1, 1, 0)))
+    # Open the tag.
+    s = ' ' * indent + '<' + node.tagName
+
+    # Calculate how much space to allow for the '>' or '/>'.
+    closing_chars = 1
+    if not node.childNodes:
+      closing_chars = 2
+
+    attributes = node.attributes.keys()
+    required_attributes = [attribute for attribute in self.required_attributes
+                           if attribute in self.attribute_order[node.tagName]]
+    missing_attributes = [attribute for attribute in required_attributes
+                          if attribute not in attributes]
+
+    for attribute in missing_attributes:
+      logging.error(
+          'Missing attribute "%s" in tag "%s"', attribute, node.tagName)
+    if missing_attributes:
+      missing_attributes_str = (
+          ', '.join('"%s"' % attribute for attribute in missing_attributes))
+      present_attributes = [
+          ' {0}="{1}"'.format(name, value)
+          for name, value in node.attributes.items()]
+      node_str = '<{0}{1}>'.format(node.tagName, ''.join(present_attributes))
+      raise Error(
+          'Missing attributes {0} in tag "{1}"'.format(
+              missing_attributes_str, node_str))
+
+    # Pretty-print the attributes.
+    if attributes:
+      # Reorder the attributes.
+      unrecognized_attributes = (
+          [a for a in attributes
+           if a not in self.attribute_order[node.tagName]])
+      attributes = [a for a in self.attribute_order[node.tagName]
+                    if a in attributes]
+
+      for a in unrecognized_attributes:
+        logging.error(
+            'Unrecognized attribute "%s" in tag "%s"', a, node.tagName)
+      if unrecognized_attributes:
+        raise Error(
+            'Unrecognized attributes {0} in tag "{1}"'.format(
+                ', '.join('"{0}"'.format(a) for a in unrecognized_attributes),
+                node.tagName))
+
+      for a in attributes:
+        value = XmlEscape(node.attributes[a].value)
+        # Replace sequences of whitespace with single spaces.
+        words = value.split()
+        a_str = ' %s="%s"' % (a, ' '.join(words))
+        # Start a new line if the attribute will make this line too long.
+        if LastLineLength(s) + len(a_str) + closing_chars > WRAP_COLUMN:
+          s += '\n' + ' ' * (indent + 3)
+        # Output everything up to the first quote.
+        s += ' %s="' % (a)
+        value_indent_level = LastLineLength(s)
+        # Output one word at a time, splitting to the next line where
+        # necessary.
+        column = value_indent_level
+        for i, word in enumerate(words):
+          # This is slightly too conservative since not every word will be
+          # followed by the closing characters...
+          if i > 0 and (column + len(word) + 1 + closing_chars > WRAP_COLUMN):
+            s = s.rstrip()  # remove any trailing whitespace
+            s += '\n' + ' ' * value_indent_level
+            column = value_indent_level
+          s += word + ' '
+          column += len(word) + 1
+        s = s.rstrip()  # remove any trailing whitespace
+        s += '"'
+      s = s.rstrip()  # remove any trailing whitespace
+
+    # Pretty-print the child nodes.
+    if node.childNodes:
+      s += '>'
+      # Calculate the new indent level for child nodes.
+      new_indent = indent
+      if node.tagName not in self.tags_that_dont_indent:
+        new_indent += 2
+      child_nodes = node.childNodes
+
+      # Recursively pretty-print the child nodes.
+      child_nodes = [self.PrettyPrintNode(n, indent=new_indent)
+                     for n in child_nodes]
+      child_nodes = [c for c in child_nodes if c.strip()]
+
+      # Determine whether we can fit the entire node on a single line.
+      close_tag = '</%s>' % node.tagName
+      space_left = WRAP_COLUMN - LastLineLength(s) - len(close_tag)
+      if (node.tagName in self.tags_that_allow_single_line and
+          len(child_nodes) == 1 and
+          len(child_nodes[0].strip()) <= space_left):
+        s += child_nodes[0].strip()
+      else:
+        s += '\n' * newlines_after_open + '\n'.join(child_nodes)
+        s += '\n' * newlines_before_close + ' ' * indent
+      s += close_tag
+    else:
+      s += '/>'
+    s += '\n' * newlines_after_close
+    return s
+
   def PrettyPrintNode(self, node, indent=0):
     """Pretty-prints the given XML node at the given indent level.
 
@@ -177,130 +303,11 @@
 
     # Handle text nodes.
     if node.nodeType == xml.dom.minidom.Node.TEXT_NODE:
-      # Wrap each paragraph in the text to fit in the 80 column limit.
-      wrapper = textwrap.TextWrapper()
-      wrapper.initial_indent = ' ' * indent
-      wrapper.subsequent_indent = ' ' * indent
-      wrapper.break_on_hyphens = False
-      wrapper.break_long_words = False
-      wrapper.width = WRAP_COLUMN
-      text = XmlEscape(node.data)
-      paragraphs = SplitParagraphs(text)
-      # Wrap each paragraph and separate with two newlines.
-      return '\n\n'.join(wrapper.fill(p) for p in paragraphs)
+      return self._PrettyPrintText(node, indent)
 
     # Handle element nodes.
     if node.nodeType == xml.dom.minidom.Node.ELEMENT_NODE:
-      # Check if tag name is valid.
-      if node.tagName not in self.attribute_order:
-        logging.error('Unrecognized tag "%s"', node.tagName)
-        raise Error('Unrecognized tag "%s"', node.tagName)
-
-      # Newlines.
-      newlines_after_open, newlines_before_close, newlines_after_close = (
-          self.tags_that_have_extra_newline.get(node.tagName, (1, 1, 0)))
-      # Open the tag.
-      s = ' ' * indent + '<' + node.tagName
-
-      # Calculate how much space to allow for the '>' or '/>'.
-      closing_chars = 1
-      if not node.childNodes:
-        closing_chars = 2
-
-      attributes = node.attributes.keys()
-      required_attributes = [attribute for attribute in self.required_attributes
-                             if attribute in self.attribute_order[node.tagName]]
-      missing_attributes = [attribute for attribute in required_attributes
-                            if attribute not in attributes]
-
-      for attribute in missing_attributes:
-        logging.error(
-            'Missing attribute "%s" in tag "%s"', attribute, node.tagName)
-      if missing_attributes:
-        missing_attributes_str = (
-            ', '.join('"%s"' % attribute for attribute in missing_attributes))
-        present_attributes = [
-            ' {0}="{1}"'.format(name, value)
-            for name, value in node.attributes.items()]
-        node_str = '<{0}{1}>'.format(node.tagName, ''.join(present_attributes))
-        raise Error(
-            'Missing attributes {0} in tag "{1}"'.format(
-                missing_attributes_str, node_str))
-
-      # Pretty-print the attributes.
-      if attributes:
-        # Reorder the attributes.
-        unrecognized_attributes = (
-            [a for a in attributes
-             if a not in self.attribute_order[node.tagName]])
-        attributes = [a for a in self.attribute_order[node.tagName]
-                      if a in attributes]
-
-        for a in unrecognized_attributes:
-          logging.error(
-              'Unrecognized attribute "%s" in tag "%s"', a, node.tagName)
-        if unrecognized_attributes:
-          raise Error(
-              'Unrecognized attributes {0} in tag "{1}"'.format(
-                  ', '.join('"{0}"'.format(a) for a in unrecognized_attributes),
-                  node.tagName))
-
-        for a in attributes:
-          value = XmlEscape(node.attributes[a].value)
-          # Replace sequences of whitespace with single spaces.
-          words = value.split()
-          a_str = ' %s="%s"' % (a, ' '.join(words))
-          # Start a new line if the attribute will make this line too long.
-          if LastLineLength(s) + len(a_str) + closing_chars > WRAP_COLUMN:
-            s += '\n' + ' ' * (indent + 3)
-          # Output everything up to the first quote.
-          s += ' %s="' % (a)
-          value_indent_level = LastLineLength(s)
-          # Output one word at a time, splitting to the next line where
-          # necessary.
-          column = value_indent_level
-          for i, word in enumerate(words):
-            # This is slightly too conservative since not every word will be
-            # followed by the closing characters...
-            if i > 0 and (column + len(word) + 1 + closing_chars > WRAP_COLUMN):
-              s = s.rstrip()  # remove any trailing whitespace
-              s += '\n' + ' ' * value_indent_level
-              column = value_indent_level
-            s += word + ' '
-            column += len(word) + 1
-          s = s.rstrip()  # remove any trailing whitespace
-          s += '"'
-        s = s.rstrip()  # remove any trailing whitespace
-
-      # Pretty-print the child nodes.
-      if node.childNodes:
-        s += '>'
-        # Calculate the new indent level for child nodes.
-        new_indent = indent
-        if node.tagName not in self.tags_that_dont_indent:
-          new_indent += 2
-        child_nodes = node.childNodes
-
-        # Recursively pretty-print the child nodes.
-        child_nodes = [self.PrettyPrintNode(n, indent=new_indent)
-                       for n in child_nodes]
-        child_nodes = [c for c in child_nodes if c.strip()]
-
-        # Determine whether we can fit the entire node on a single line.
-        close_tag = '</%s>' % node.tagName
-        space_left = WRAP_COLUMN - LastLineLength(s) - len(close_tag)
-        if (node.tagName in self.tags_that_allow_single_line and
-            len(child_nodes) == 1 and
-            len(child_nodes[0].strip()) <= space_left):
-          s += child_nodes[0].strip()
-        else:
-          s += '\n' * newlines_after_open + '\n'.join(child_nodes)
-          s += '\n' * newlines_before_close + ' ' * indent
-        s += close_tag
-      else:
-        s += '/>'
-      s += '\n' * newlines_after_close
-      return s
+      return self._PrettyPrintElement(node, indent)
 
     # Handle comment nodes.
     if node.nodeType == xml.dom.minidom.Node.COMMENT_NODE:
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 2e9e178..bb8a743 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -8510,10 +8510,7 @@
 <enum name="CompositorFrameSinkSubmitResult">
   <int value="0" label="Accepted"/>
   <int value="1" label="CopyOutputResults not allowed"/>
-  <int value="2" label="Surface Invariants Violation (deprecated)"/>
-  <int value="3" label="Size mismatch"/>
-  <int value="4" label="SurfaceId sequence numbers decreased"/>
-  <int value="5" label="Surface owned by another client"/>
+  <int value="2" label="Surface Invariants Violation"/>
 </enum>
 
 <enum name="CompositorScrollResult">
@@ -22732,6 +22729,7 @@
   <int value="43" label="Hid"/>
   <int value="44" label="IdleDetection"/>
   <int value="45" label="UnoptimizedLossyImages"/>
+  <int value="46" label="UnoptimizedLosslessImages"/>
 </enum>
 
 <enum name="FeedbackSource">
@@ -32718,6 +32716,7 @@
   <int value="-966290456" label="WebAuthenticationCtap2:enabled"/>
   <int value="-965842218" label="MultiDeviceApi:disabled"/>
   <int value="-964676765" label="enable-accelerated-mjpeg-decode"/>
+  <int value="-957200826" label="enable-spdy-proxy-auth"/>
   <int value="-956696029" label="scheduler-configuration"/>
   <int value="-951394314" label="top-chrome-md"/>
   <int value="-950793721" label="TranslateUI2016Q2:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 622fc06d..9b1b5f8 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -119031,7 +119031,7 @@
 
 <histogram
     name="Sync.Crypto.CustomPassphraseKeyDerivationMethodOnNewPassphrase"
-    enum="SyncCustomPassphraseKeyDerivationMethodState" expires_after="M75">
+    enum="SyncCustomPassphraseKeyDerivationMethodState" expires_after="M77">
   <owner>vitaliii@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -119044,7 +119044,7 @@
 
 <histogram
     name="Sync.Crypto.CustomPassphraseKeyDerivationMethodOnSuccessfulDecryption"
-    enum="SyncCustomPassphraseKeyDerivationMethodState" expires_after="M75">
+    enum="SyncCustomPassphraseKeyDerivationMethodState" expires_after="M77">
   <owner>vitaliii@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -119057,7 +119057,7 @@
 </histogram>
 
 <histogram name="Sync.Crypto.CustomPassphraseKeyDerivationMethodStateOnStartup"
-    enum="SyncCustomPassphraseKeyDerivationMethodState" expires_after="M75">
+    enum="SyncCustomPassphraseKeyDerivationMethodState" expires_after="M77">
   <owner>vitaliii@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
diff --git a/tools/perf/page_sets/data/system_health_mobile.json b/tools/perf/page_sets/data/system_health_mobile.json
index 496be5c..3509983 100644
--- a/tools/perf/page_sets/data/system_health_mobile.json
+++ b/tools/perf/page_sets/data/system_health_mobile.json
@@ -27,15 +27,15 @@
         "browse:media:flickr_infinite_scroll": {
             "DEFAULT": "system_health_mobile_062.wprgo"
         },
+        "browse:media:googleplaystore:2019": {
+            "DEFAULT": "system_health_mobile_4413a28712.wprgo"
+        },
         "browse:media:imgur": {
             "DEFAULT": "system_health_mobile_035.wprgo"
         },
         "browse:media:youtube": {
             "DEFAULT": "system_health_mobile_037.wprgo"
         },
-        "browse:media:googleplaystore:2019": {
-            "DEFAULT": "system_health_mobile_4413a28712.wprgo"
-        },
         "browse:news:cnn": {
             "DEFAULT": "system_health_mobile_014.wprgo"
         },
@@ -72,6 +72,9 @@
         "browse:search:amp:2018": {
             "DEFAULT": "system_health_mobile_0483ae239d.wprgo"
         },
+        "browse:search:amp:sxg:2019": {
+            "DEFAULT": "system_health_mobile_d7a7409e72.wprgo"
+        },
         "browse:shopping:amazon": {
             "DEFAULT": "system_health_mobile_053.wprgo"
         },
@@ -294,4 +297,4 @@
     },
     "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
     "platform_specific": true
-}
+}
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile_d7a7409e72.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_d7a7409e72.wprgo.sha1
new file mode 100644
index 0000000..c09f3aa6
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_mobile_d7a7409e72.wprgo.sha1
@@ -0,0 +1 @@
+d7a7409e72e323d0b2c3b01e60b412c970702e6f
\ No newline at end of file
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py
index c91e49a..21eaf48 100644
--- a/tools/perf/page_sets/system_health/browsing_stories.py
+++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -397,6 +397,32 @@
     action_runner.ClickElement(element_function=element_function)
     action_runner.Wait(2)
 
+class GoogleAmpSXGStory2019(_ArticleBrowsingStory):
+  """ Story for Google's Signed Exchange (SXG) Accelerated Mobile Pages (AMP).
+  """
+  NAME = 'browse:search:amp:sxg:2019'
+  # Specific URL for site that supports SXG, travel.yahoo.co.jp
+  # pylint: disable=line-too-long
+  URL='https://www.google.com/search?q=%E5%85%AD%E6%9C%AC%E6%9C%A8%E3%80%80%E3%83%A4%E3%83%95%E3%83%BC%E3%80%80%E3%83%9B%E3%83%86%E3%83%AB&esrch=SignedExchange::Demo'
+  # Need to find the SXG AMPlink in the results
+  ITEM_SELECTOR = 'a > div > span[aria-label="AMP logo"]'
+  SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
+  TAGS = [story_tags.YEAR_2019]
+
+  def _DidLoadDocument(self, action_runner):
+    # Waiting manually for the search results to load here and below.
+    # Telemetry's action_runner.WaitForNavigate has some difficulty with amp
+    # pages as it waits for a frameId without a parent id.
+    action_runner.Wait(2)
+    # Click on the yahoo amp link and then just wait for it to load.
+    element_function = js_template.Render(
+        'document.querySelectorAll({{ selector }})[{{ index }}]',
+        selector=self.ITEM_SELECTOR, index=0)
+    action_runner.WaitForElement(element_function=element_function)
+    action_runner.ClickElement(element_function=element_function)
+    # Waiting for the document to fully render
+    action_runner.Wait(2)
+
 
 class GoogleDesktopStory2018(_ArticleBrowsingStory):
   """