diff --git a/tools/warn/html_writer.py b/tools/warn/html_writer.py
new file mode 100644
index 0000000..b8d3fe6
--- /dev/null
+++ b/tools/warn/html_writer.py
@@ -0,0 +1,673 @@
+# Lint as: python3
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Emit warning messages to html or csv files."""
+
+# To emit html page of warning messages:
+#   flags: --byproject, --url, --separator
+# Old stuff for static html components:
+#   html_script_style:  static html scripts and styles
+#   htmlbig:
+#   dump_stats, dump_html_prologue, dump_html_epilogue:
+#   emit_buttons:
+#   dump_fixed
+#   sort_warnings:
+#   emit_stats_by_project:
+#   all_patterns,
+#   findproject, classify_warning
+#   dump_html
+#
+# New dynamic HTML page's static JavaScript data:
+#   Some data are copied from Python to JavaScript, to generate HTML elements.
+#   FlagPlatform           flags.platform
+#   FlagURL                flags.url, used by 'android'
+#   FlagSeparator          flags.separator, used by 'android'
+#   SeverityColors:        list of colors for all severity levels
+#   SeverityHeaders:       list of headers for all severity levels
+#   SeverityColumnHeaders: list of column_headers for all severity levels
+#   ProjectNames:          project_names, or project_list[*][0]
+#   WarnPatternsSeverity:     warn_patterns[*]['severity']
+#   WarnPatternsDescription:  warn_patterns[*]['description']
+#   WarningMessages:          warning_messages
+#   Warnings:                 warning_records
+#   StatsHeader:           warning count table header row
+#   StatsRows:             array of warning count table rows
+#
+# New dynamic HTML page's dynamic JavaScript data:
+#
+# New dynamic HTML related function to emit data:
+#   escape_string, strip_escape_string, emit_warning_arrays
+#   emit_js_data():
+
+from __future__ import print_function
+import cgi
+import csv
+import sys
+
+# pylint:disable=relative-beyond-top-level
+# pylint:disable=g-importing-member
+from .severity import Severity
+
+
+html_head_scripts = """\
+  <script type="text/javascript">
+  function expand(id) {
+    var e = document.getElementById(id);
+    var f = document.getElementById(id + "_mark");
+    if (e.style.display == 'block') {
+       e.style.display = 'none';
+       f.innerHTML = '&#x2295';
+    }
+    else {
+       e.style.display = 'block';
+       f.innerHTML = '&#x2296';
+    }
+  };
+  function expandCollapse(show) {
+    for (var id = 1; ; id++) {
+      var e = document.getElementById(id + "");
+      var f = document.getElementById(id + "_mark");
+      if (!e || !f) break;
+      e.style.display = (show ? 'block' : 'none');
+      f.innerHTML = (show ? '&#x2296' : '&#x2295');
+    }
+  };
+  </script>
+  <style type="text/css">
+  th,td{border-collapse:collapse; border:1px solid black;}
+  .button{color:blue;font-size:110%;font-weight:bolder;}
+  .bt{color:black;background-color:transparent;border:none;outline:none;
+      font-size:140%;font-weight:bolder;}
+  .c0{background-color:#e0e0e0;}
+  .c1{background-color:#d0d0d0;}
+  .t1{border-collapse:collapse; width:100%; border:1px solid black;}
+  </style>
+  <script src="https://www.gstatic.com/charts/loader.js"></script>
+"""
+
+
+def make_writer(output_stream):
+
+  def writer(text):
+    return output_stream.write(text + '\n')
+
+  return writer
+
+
+def html_big(param):
+  return '<font size="+2">' + param + '</font>'
+
+
+def dump_html_prologue(title, writer, warn_patterns, project_names):
+  writer('<html>\n<head>')
+  writer('<title>' + title + '</title>')
+  writer(html_head_scripts)
+  emit_stats_by_project(writer, warn_patterns, project_names)
+  writer('</head>\n<body>')
+  writer(html_big(title))
+  writer('<p>')
+
+
+def dump_html_epilogue(writer):
+  writer('</body>\n</head>\n</html>')
+
+
+def sort_warnings(warn_patterns):
+  for i in warn_patterns:
+    i['members'] = sorted(set(i['members']))
+
+
+def create_warnings(warn_patterns, project_names):
+  """Creates warnings s.t.
+
+  warnings[p][s] is as specified in above docs.
+
+  Args:
+    warn_patterns: list of warning patterns for specified platform
+    project_names: list of project names
+
+  Returns:
+    2D warnings array where warnings[p][s] is # of warnings in project name p of
+    severity level s
+  """
+  # pylint:disable=g-complex-comprehension
+  warnings = {p: {s.value: 0 for s in Severity.levels} for p in project_names}
+  for i in warn_patterns:
+    s = i['severity'].value
+    for p in i['projects']:
+      warnings[p][s] += i['projects'][p]
+  return warnings
+
+
+def get_total_by_project(warnings, project_names):
+  """Returns dict, project as key and # warnings for that project as value."""
+  # pylint:disable=g-complex-comprehension
+  return {
+      p: sum(warnings[p][s.value] for s in Severity.levels)
+      for p in project_names
+  }
+
+
+def get_total_by_severity(warnings, project_names):
+  """Returns dict, severity as key and # warnings of that severity as value."""
+  # pylint:disable=g-complex-comprehension
+  return {
+      s.value: sum(warnings[p][s.value] for p in project_names)
+      for s in Severity.levels
+  }
+
+
+def emit_table_header(total_by_severity):
+  """Returns list of HTML-formatted content for severity stats."""
+
+  stats_header = ['Project']
+  for s in Severity.levels:
+    if total_by_severity[s.value]:
+      stats_header.append(
+          '<span style=\'background-color:{}\'>{}</span>'.format(
+              s.color, s.column_header))
+  stats_header.append('TOTAL')
+  return stats_header
+
+
+def emit_row_counts_per_project(warnings, total_by_project, total_by_severity,
+                                project_names):
+  """Returns total project warnings and row of stats for each project.
+
+  Args:
+    warnings: output of create_warnings(warn_patterns, project_names)
+    total_by_project: output of get_total_by_project(project_names)
+    total_by_severity: output of get_total_by_severity(project_names)
+    project_names: list of project names
+
+  Returns:
+    total_all_projects, the total number of warnings over all projects
+    stats_rows, a 2d list where each row is [Project Name, <severity counts>,
+    total # warnings for this project]
+  """
+
+  total_all_projects = 0
+  stats_rows = []
+  for p in project_names:
+    if total_by_project[p]:
+      one_row = [p]
+      for s in Severity.levels:
+        if total_by_severity[s.value]:
+          one_row.append(warnings[p][s.value])
+      one_row.append(total_by_project[p])
+      stats_rows.append(one_row)
+      total_all_projects += total_by_project[p]
+  return total_all_projects, stats_rows
+
+
+def emit_row_counts_per_severity(total_by_severity, stats_header, stats_rows,
+                                 total_all_projects, writer):
+  """Emits stats_header and stats_rows as specified above.
+
+  Args:
+    total_by_severity: output of get_total_by_severity()
+    stats_header: output of emit_table_header()
+    stats_rows: output of emit_row_counts_per_project()
+    total_all_projects: output of emit_row_counts_per_project()
+    writer: writer returned by make_writer(output_stream)
+  """
+
+  total_all_severities = 0
+  one_row = ['<b>TOTAL</b>']
+  for s in Severity.levels:
+    if total_by_severity[s.value]:
+      one_row.append(total_by_severity[s.value])
+      total_all_severities += total_by_severity[s.value]
+  one_row.append(total_all_projects)
+  stats_rows.append(one_row)
+  writer('<script>')
+  emit_const_string_array('StatsHeader', stats_header, writer)
+  emit_const_object_array('StatsRows', stats_rows, writer)
+  writer(draw_table_javascript)
+  writer('</script>')
+
+
+def emit_stats_by_project(writer, warn_patterns, project_names):
+  """Dump a google chart table of warnings per project and severity."""
+
+  warnings = create_warnings(warn_patterns, project_names)
+  total_by_project = get_total_by_project(warnings, project_names)
+  total_by_severity = get_total_by_severity(warnings, project_names)
+  stats_header = emit_table_header(total_by_severity)
+  total_all_projects, stats_rows = \
+    emit_row_counts_per_project(warnings, total_by_project, total_by_severity, project_names)
+  emit_row_counts_per_severity(total_by_severity, stats_header, stats_rows,
+                               total_all_projects, writer)
+
+
+def dump_stats(writer, warn_patterns):
+  """Dump some stats about total number of warnings and such."""
+
+  known = 0
+  skipped = 0
+  unknown = 0
+  sort_warnings(warn_patterns)
+  for i in warn_patterns:
+    if i['severity'] == Severity.UNMATCHED:
+      unknown += len(i['members'])
+    elif i['severity'] == Severity.SKIP:
+      skipped += len(i['members'])
+    else:
+      known += len(i['members'])
+  writer('Number of classified warnings: <b>' + str(known) + '</b><br>')
+  writer('Number of skipped warnings: <b>' + str(skipped) + '</b><br>')
+  writer('Number of unclassified warnings: <b>' + str(unknown) + '</b><br>')
+  total = unknown + known + skipped
+  extra_msg = ''
+  if total < 1000:
+    extra_msg = ' (low count may indicate incremental build)'
+  writer('Total number of warnings: <b>' + str(total) + '</b>' + extra_msg)
+
+
+# New base table of warnings, [severity, warn_id, project, warning_message]
+# Need buttons to show warnings in different grouping options.
+# (1) Current, group by severity, id for each warning pattern
+#     sort by severity, warn_id, warning_message
+# (2) Current --byproject, group by severity,
+#     id for each warning pattern + project name
+#     sort by severity, warn_id, project, warning_message
+# (3) New, group by project + severity,
+#     id for each warning pattern
+#     sort by project, severity, warn_id, warning_message
+def emit_buttons(writer):
+  writer('<button class="button" onclick="expandCollapse(1);">'
+         'Expand all warnings</button>\n'
+         '<button class="button" onclick="expandCollapse(0);">'
+         'Collapse all warnings</button>\n'
+         '<button class="button" onclick="groupBySeverity();">'
+         'Group warnings by severity</button>\n'
+         '<button class="button" onclick="groupByProject();">'
+         'Group warnings by project</button><br>')
+
+
+def all_patterns(category):
+  patterns = ''
+  for i in category['patterns']:
+    patterns += i
+    patterns += ' / '
+  return patterns
+
+
+def dump_fixed(writer, warn_patterns):
+  """Show which warnings no longer occur."""
+  anchor = 'fixed_warnings'
+  mark = anchor + '_mark'
+  writer('\n<br><p style="background-color:lightblue"><b>'
+         '<button id="' + mark + '" '
+         'class="bt" onclick="expand(\'' + anchor + '\');">'
+         '&#x2295</button> Fixed warnings. '
+         'No more occurrences. Please consider turning these into '
+         'errors if possible, before they are reintroduced in to the build'
+         ':</b></p>')
+  writer('<blockquote>')
+  fixed_patterns = []
+  for i in warn_patterns:
+    if not i['members']:
+      fixed_patterns.append(i['description'] + ' (' + all_patterns(i) + ')')
+  fixed_patterns = sorted(fixed_patterns)
+  writer('<div id="' + anchor + '" style="display:none;"><table>')
+  cur_row_class = 0
+  for text in fixed_patterns:
+    cur_row_class = 1 - cur_row_class
+    # remove last '\n'
+    t = text[:-1] if text[-1] == '\n' else text
+    writer('<tr><td class="c' + str(cur_row_class) + '">' + t + '</td></tr>')
+  writer('</table></div>')
+  writer('</blockquote>')
+
+
+def write_severity(csvwriter, sev, kind, warn_patterns):
+  """Count warnings of given severity and write CSV entries to writer."""
+  total = 0
+  for pattern in warn_patterns:
+    if pattern['severity'] == sev and pattern['members']:
+      n = len(pattern['members'])
+      total += n
+      warning = kind + ': ' + (pattern['description'] or '?')
+      csvwriter.writerow([n, '', warning])
+      # print number of warnings for each project, ordered by project name
+      projects = sorted(pattern['projects'].keys())
+      for project in projects:
+        csvwriter.writerow([pattern['projects'][project], project, warning])
+  csvwriter.writerow([total, '', kind + ' warnings'])
+  return total
+
+
+def dump_csv(csvwriter, warn_patterns):
+  """Dump number of warnings in CSV format to writer."""
+  sort_warnings(warn_patterns)
+  total = 0
+  for s in Severity.levels:
+    total += write_severity(csvwriter, s, s.column_header, warn_patterns)
+  csvwriter.writerow([total, '', 'All warnings'])
+
+
+# Return s with escaped backslash and quotation characters.
+def escape_string(s):
+  return s.replace('\\', '\\\\').replace('"', '\\"')
+
+
+# Return s without trailing '\n' and escape the quotation characters.
+def strip_escape_string(s):
+  if not s:
+    return s
+  s = s[:-1] if s[-1] == '\n' else s
+  return escape_string(s)
+
+
+def emit_warning_array(name, writer, warn_patterns):
+  writer('var warning_{} = ['.format(name))
+  for w in warn_patterns:
+    if name == 'severity':
+      writer('{},'.format(w[name].value))
+    else:
+      writer('{},'.format(w[name]))
+  writer('];')
+
+
+def emit_warning_arrays(writer, warn_patterns):
+  emit_warning_array('severity', writer, warn_patterns)
+  writer('var warning_description = [')
+  for w in warn_patterns:
+    if w['members']:
+      writer('"{}",'.format(escape_string(w['description'])))
+    else:
+      writer('"",')  # no such warning
+  writer('];')
+
+
+scripts_for_warning_groups = """
+  function compareMessages(x1, x2) { // of the same warning type
+    return (WarningMessages[x1[2]] <= WarningMessages[x2[2]]) ? -1 : 1;
+  }
+  function byMessageCount(x1, x2) {
+    return x2[2] - x1[2];  // reversed order
+  }
+  function bySeverityMessageCount(x1, x2) {
+    // orer by severity first
+    if (x1[1] != x2[1])
+      return  x1[1] - x2[1];
+    return byMessageCount(x1, x2);
+  }
+  const ParseLinePattern = /^([^ :]+):(\\d+):(.+)/;
+  function addURL(line) { // used by Android
+    if (FlagURL == "") return line;
+    if (FlagSeparator == "") {
+      return line.replace(ParseLinePattern,
+        "<a target='_blank' href='" + FlagURL + "/$1'>$1</a>:$2:$3");
+    }
+    return line.replace(ParseLinePattern,
+      "<a target='_blank' href='" + FlagURL + "/$1" + FlagSeparator +
+        "$2'>$1:$2</a>:$3");
+  }
+  function addURLToLine(line, link) { // used by Chrome
+      let line_split = line.split(":");
+      let path = line_split.slice(0,3).join(":");
+      let msg = line_split.slice(3).join(":");
+      let html_link = `<a target="_blank" href="${link}">${path}</a>${msg}`;
+      return html_link;
+  }
+  function createArrayOfDictionaries(n) {
+    var result = [];
+    for (var i=0; i<n; i++) result.push({});
+    return result;
+  }
+  function groupWarningsBySeverity() {
+    // groups is an array of dictionaries,
+    // each dictionary maps from warning type to array of warning messages.
+    var groups = createArrayOfDictionaries(SeverityColors.length);
+    for (var i=0; i<Warnings.length; i++) {
+      var w = Warnings[i][0];
+      var s = WarnPatternsSeverity[w];
+      var k = w.toString();
+      if (!(k in groups[s]))
+        groups[s][k] = [];
+      groups[s][k].push(Warnings[i]);
+    }
+    return groups;
+  }
+  function groupWarningsByProject() {
+    var groups = createArrayOfDictionaries(ProjectNames.length);
+    for (var i=0; i<Warnings.length; i++) {
+      var w = Warnings[i][0];
+      var p = Warnings[i][1];
+      var k = w.toString();
+      if (!(k in groups[p]))
+        groups[p][k] = [];
+      groups[p][k].push(Warnings[i]);
+    }
+    return groups;
+  }
+  var GlobalAnchor = 0;
+  function createWarningSection(header, color, group) {
+    var result = "";
+    var groupKeys = [];
+    var totalMessages = 0;
+    for (var k in group) {
+       totalMessages += group[k].length;
+       groupKeys.push([k, WarnPatternsSeverity[parseInt(k)], group[k].length]);
+    }
+    groupKeys.sort(bySeverityMessageCount);
+    for (var idx=0; idx<groupKeys.length; idx++) {
+      var k = groupKeys[idx][0];
+      var messages = group[k];
+      var w = parseInt(k);
+      var wcolor = SeverityColors[WarnPatternsSeverity[w]];
+      var description = WarnPatternsDescription[w];
+      if (description.length == 0)
+          description = "???";
+      GlobalAnchor += 1;
+      result += "<table class='t1'><tr bgcolor='" + wcolor + "'><td>" +
+                "<button class='bt' id='" + GlobalAnchor + "_mark" +
+                "' onclick='expand(\\"" + GlobalAnchor + "\\");'>" +
+                "&#x2295</button> " +
+                description + " (" + messages.length + ")</td></tr></table>";
+      result += "<div id='" + GlobalAnchor +
+                "' style='display:none;'><table class='t1'>";
+      var c = 0;
+      messages.sort(compareMessages);
+      if (FlagPlatform == "chrome") {
+        for (var i=0; i<messages.length; i++) {
+          result += "<tr><td class='c" + c + "'>" +
+                    addURLToLine(WarningMessages[messages[i][2]], WarningLinks[messages[i][3]]) + "</td></tr>";
+          c = 1 - c;
+        }
+      } else {
+        for (var i=0; i<messages.length; i++) {
+          result += "<tr><td class='c" + c + "'>" +
+                    addURL(WarningMessages[messages[i][2]]) + "</td></tr>";
+          c = 1 - c;
+        }
+      }
+      result += "</table></div>";
+    }
+    if (result.length > 0) {
+      return "<br><span style='background-color:" + color + "'><b>" +
+             header + ": " + totalMessages +
+             "</b></span><blockquote><table class='t1'>" +
+             result + "</table></blockquote>";
+
+    }
+    return "";  // empty section
+  }
+  function generateSectionsBySeverity() {
+    var result = "";
+    var groups = groupWarningsBySeverity();
+    for (s=0; s<SeverityColors.length; s++) {
+      result += createWarningSection(SeverityHeaders[s], SeverityColors[s],
+                                     groups[s]);
+    }
+    return result;
+  }
+  function generateSectionsByProject() {
+    var result = "";
+    var groups = groupWarningsByProject();
+    for (i=0; i<groups.length; i++) {
+      result += createWarningSection(ProjectNames[i], 'lightgrey', groups[i]);
+    }
+    return result;
+  }
+  function groupWarnings(generator) {
+    GlobalAnchor = 0;
+    var e = document.getElementById("warning_groups");
+    e.innerHTML = generator();
+  }
+  function groupBySeverity() {
+    groupWarnings(generateSectionsBySeverity);
+  }
+  function groupByProject() {
+    groupWarnings(generateSectionsByProject);
+  }
+"""
+
+
+# Emit a JavaScript const string
+def emit_const_string(name, value, writer):
+  writer('const ' + name + ' = "' + escape_string(value) + '";')
+
+
+# Emit a JavaScript const integer array.
+def emit_const_int_array(name, array, writer):
+  writer('const ' + name + ' = [')
+  for n in array:
+    writer(str(n) + ',')
+  writer('];')
+
+
+# Emit a JavaScript const string array.
+def emit_const_string_array(name, array, writer):
+  writer('const ' + name + ' = [')
+  for s in array:
+    writer('"' + strip_escape_string(s) + '",')
+  writer('];')
+
+
+# Emit a JavaScript const string array for HTML.
+def emit_const_html_string_array(name, array, writer):
+  writer('const ' + name + ' = [')
+  for s in array:
+    # Not using html.escape yet, to work for both python 2 and 3,
+    # until all users switch to python 3.
+    # pylint:disable=deprecated-method
+    writer('"' + cgi.escape(strip_escape_string(s)) + '",')
+  writer('];')
+
+
+# Emit a JavaScript const object array.
+def emit_const_object_array(name, array, writer):
+  writer('const ' + name + ' = [')
+  for x in array:
+    writer(str(x) + ',')
+  writer('];')
+
+
+def emit_js_data(writer, flags, warning_messages, warning_links,
+                 warning_records, warn_patterns, project_names):
+  """Dump dynamic HTML page's static JavaScript data."""
+  emit_const_string('FlagPlatform', flags.platform, writer)
+  emit_const_string('FlagURL', flags.url, writer)
+  emit_const_string('FlagSeparator', flags.separator, writer)
+  emit_const_string_array('SeverityColors', [s.color for s in Severity.levels],
+                          writer)
+  emit_const_string_array('SeverityHeaders',
+                          [s.header for s in Severity.levels], writer)
+  emit_const_string_array('SeverityColumnHeaders',
+                          [s.column_header for s in Severity.levels], writer)
+  emit_const_string_array('ProjectNames', project_names, writer)
+  # pytype: disable=attribute-error
+  emit_const_int_array('WarnPatternsSeverity',
+                       [w['severity'].value for w in warn_patterns], writer)
+  # pytype: enable=attribute-error
+  emit_const_html_string_array('WarnPatternsDescription',
+                               [w['description'] for w in warn_patterns],
+                               writer)
+  emit_const_html_string_array('WarningMessages', warning_messages, writer)
+  emit_const_object_array('Warnings', warning_records, writer)
+  if flags.platform == 'chrome':
+    emit_const_html_string_array('WarningLinks', warning_links, writer)
+
+
+draw_table_javascript = """
+google.charts.load('current', {'packages':['table']});
+google.charts.setOnLoadCallback(drawTable);
+function drawTable() {
+  var data = new google.visualization.DataTable();
+  data.addColumn('string', StatsHeader[0]);
+  for (var i=1; i<StatsHeader.length; i++) {
+    data.addColumn('number', StatsHeader[i]);
+  }
+  data.addRows(StatsRows);
+  for (var i=0; i<StatsRows.length; i++) {
+    for (var j=0; j<StatsHeader.length; j++) {
+      data.setProperty(i, j, 'style', 'border:1px solid black;');
+    }
+  }
+  var table = new google.visualization.Table(
+      document.getElementById('stats_table'));
+  table.draw(data, {allowHtml: true, alternatingRowStyle: true});
+}
+"""
+
+
+def dump_html(flags, output_stream, warning_messages, warning_links,
+              warning_records, header_str, warn_patterns, project_names):
+  """Dump the flags output to output_stream."""
+  writer = make_writer(output_stream)
+  dump_html_prologue('Warnings for ' + header_str, writer, warn_patterns,
+                     project_names)
+  dump_stats(writer, warn_patterns)
+  writer('<br><div id="stats_table"></div><br>')
+  writer('\n<script>')
+  emit_js_data(writer, flags, warning_messages, warning_links, warning_records,
+               warn_patterns, project_names)
+  writer(scripts_for_warning_groups)
+  writer('</script>')
+  emit_buttons(writer)
+  # Warning messages are grouped by severities or project names.
+  writer('<br><div id="warning_groups"></div>')
+  if flags.byproject:
+    writer('<script>groupByProject();</script>')
+  else:
+    writer('<script>groupBySeverity();</script>')
+  dump_fixed(writer, warn_patterns)
+  dump_html_epilogue(writer)
+
+
+def write_html(flags, project_names, warn_patterns, html_path, warning_messages,
+               warning_links, warning_records, header_str):
+  """Write warnings html file."""
+  if html_path:
+    with open(html_path, 'w') as f:
+      dump_html(flags, f, warning_messages, warning_links, warning_records,
+                header_str, warn_patterns, project_names)
+
+
+def write_out_csv(flags, warn_patterns, warning_messages, warning_links,
+                  warning_records, header_str, project_names):
+  """Write warnings csv file."""
+  if flags.csvpath:
+    with open(flags.csvpath, 'w') as f:
+      dump_csv(csv.writer(f, lineterminator='\n'), warn_patterns)
+
+  if flags.gencsv:
+    dump_csv(csv.writer(sys.stdout, lineterminator='\n'), warn_patterns)
+  else:
+    dump_html(flags, sys.stdout, warning_messages, warning_links,
+              warning_records, header_str, warn_patterns, project_names)
