Copy improvement directions from telemetry to legacy_unit_info.

Currently, all Histograms produced by converting chart-json lack improvement
direction, even legacy units whose names indicate it.
This CL adds improvement direction to legacy units so that legacy
benchmarks like blink_perf can display green/red delta scalars and significance
emoji.

https://benjhayden.users.x20web.corp.google.com/www/2924103002.html?r=blink_perf.css%0A2017-06-08%2016%3A50%3A53&s=%CE%94avg&g=name
Review-Url: https://codereview.chromium.org/2924103002
diff --git a/tracing/tracing/value/chart_json_converter.html b/tracing/tracing/value/chart_json_converter.html
index f0c4609..fee52b3 100644
--- a/tracing/tracing/value/chart_json_converter.html
+++ b/tracing/tracing/value/chart_json_converter.html
@@ -29,11 +29,21 @@
 
           const unitInfo = tr.v.LEGACY_UNIT_INFO.get(value.units) || {};
           const unitName = unitInfo.name || 'unitlessNumber';
-          const unitNameSuffix = tr.b.Unit.nameSuffixForImprovementDirection(
-              ChartJsonConverter.convertImprovementDirection(
-                  value.improvement_direction));
           const conversionFactor = unitInfo.conversionFactor || 1;
 
+          let improvementDirection = tr.b.ImprovementDirection.DONT_CARE;
+          if (unitInfo.defaultImprovementDirection !== undefined) {
+            improvementDirection = unitInfo.defaultImprovementDirection;
+          }
+          // Metrics have the final say.
+          if (value.improvement_direction !== undefined) {
+            improvementDirection =
+              ChartJsonConverter.convertImprovementDirection(
+                  value.improvement_direction);
+          }
+          const unitNameSuffix = tr.b.Unit.nameSuffixForImprovementDirection(
+              improvementDirection);
+
           const hist = new tr.v.Histogram(
               value.name,
               tr.b.Unit.byName[unitName + unitNameSuffix],
diff --git a/tracing/tracing/value/chart_json_converter_test.html b/tracing/tracing/value/chart_json_converter_test.html
index b4aff01..ecb2f02 100644
--- a/tracing/tracing/value/chart_json_converter_test.html
+++ b/tracing/tracing/value/chart_json_converter_test.html
@@ -175,7 +175,8 @@
         tr.v.HistogramSet.GROUPINGS.STORY_NAME.callback(hist));
     assert.strictEqual(20, hist.average);
     assert.strictEqual(4, hist.numValues);
-    assert.strictEqual(tr.b.Unit.byName.timeDurationInMs, hist.unit);
+    assert.strictEqual(tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,
+        hist.unit);
   });
 });
 </script>
diff --git a/tracing/tracing/value/legacy_unit_info.html b/tracing/tracing/value/legacy_unit_info.html
index 2c9b558..8146385 100644
--- a/tracing/tracing/value/legacy_unit_info.html
+++ b/tracing/tracing/value/legacy_unit_info.html
@@ -10,72 +10,255 @@
 <script>
 'use strict';
 tr.exportTo('tr.v', function() {
+  // This information is used to convert results from chart-json format to
+  // Histograms.
+  // Improvement directions are copied from
+  // telemetry/telemetry/value/unit-info.json
+  // but can be overridden by 'improvement_direction' in chart-json.
   const LEGACY_UNIT_INFO = new Map();
-  LEGACY_UNIT_INFO.set('%', {name: 'normalizedPercentage'});
-  LEGACY_UNIT_INFO.set('', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('Celsius', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('Hz', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('KB', {name: 'sizeInBytes', conversionFactor: 1024});
+  LEGACY_UNIT_INFO.set('%', {
+    name: 'normalizedPercentage',
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.DONT_CARE,
+  });
+  LEGACY_UNIT_INFO.set('Celsius', {
+    name: 'unitlessNumber',
+    // Colder machines are faster.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('Hz', {
+    name: 'unitlessNumber',
+    // Higher frequencies are faster.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('KB', {
+    name: 'sizeInBytes',
+    conversionFactor: 1024,
+    // Less memory usage is better.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
   LEGACY_UNIT_INFO.set('MB', {
     name: 'sizeInBytes',
     conversionFactor: 1024 * 1024,
+    // Less memory usage is better.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
   });
-  LEGACY_UNIT_INFO.set('ObjectsAt30FPS', {name: 'unitlessNumber'});
+  LEGACY_UNIT_INFO.set('ObjectsAt30FPS', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
   LEGACY_UNIT_INFO.set('available_kB', {
     name: 'sizeInBytes',
     conversionFactor: 1024,
+    // More memory available is better.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
   });
-  LEGACY_UNIT_INFO.set('bit/s', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('bytes', {name: 'sizeInBytes'});
-  LEGACY_UNIT_INFO.set('chars/s', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('commit_count', {name: 'count'});
-  LEGACY_UNIT_INFO.set('count', {name: 'count'});
-  LEGACY_UNIT_INFO.set('coverage%', {name: 'normalizedPercentage'});
-  LEGACY_UNIT_INFO.set('dB', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('files', {name: 'count'});
-  LEGACY_UNIT_INFO.set('fps', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('frame_count', {name: 'count'});
-  LEGACY_UNIT_INFO.set('frame_time', {name: 'timeDurationInMs'});
-  LEGACY_UNIT_INFO.set('frames', {name: 'count'});
-  LEGACY_UNIT_INFO.set('frames-per-second', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('garbage_collections', {name: 'count'});
-  LEGACY_UNIT_INFO.set('idle%', {name: 'normalizedPercentage'});
-  LEGACY_UNIT_INFO.set('janks', {name: 'count'});
-  LEGACY_UNIT_INFO.set('kb', {name: 'sizeInBytes', conversionFactor: 1024});
-  LEGACY_UNIT_INFO.set('lines', {name: 'count'});
-  LEGACY_UNIT_INFO.set('mWh', {name: 'energyInJoules', conversionFactor: 3.6});
-  LEGACY_UNIT_INFO.set('milliseconds', {name: 'timeDurationInMs'});
-  LEGACY_UNIT_INFO.set('milliseconds-per-frame', {name: 'timeDurationInMs'});
+  LEGACY_UNIT_INFO.set('bit/s', {
+    name: 'unitlessNumber',
+    // TODO(benjhayden): Which metrics use this? It's the opposite direction
+    // from 'chars/s'.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('bytes', {
+    name: 'sizeInBytes',
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('chars/s', {
+    name: 'unitlessNumber',
+    // TODO(benjhayden): Which metrics use this? It's the opposite direction
+    // from 'bit/s'.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('commit_count', {
+    name: 'count',
+    // layer_tree_host_perftest
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('count', {
+    name: 'count',
+    // Processes
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('coverage%', {
+    name: 'normalizedPercentage',
+    // Used in alloy-perf-test/cts%/passed.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('dB', {
+    name: 'unitlessNumber',
+    // Decibels peak signal-to-noise ratio. Used by WebRTC quality tests.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('files', {
+    name: 'count',
+    // Static initializers
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('fps', {
+    name: 'unitlessNumber',
+    // Used by scirra benchmark.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('frame_count', {
+    name: 'count',
+    // layer_tree_host_perftest
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('frame_time', {
+    name: 'timeDurationInMs',
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('frames', {
+    name: 'count',
+    // Dropped frames.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('frames-per-second', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('garbage_collections', {
+    name: 'count',
+    // Number of GCs needed to collect an object. Less is better.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('idle%', {
+    name: 'normalizedPercentage',
+    // Percentage of work done in idle time.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('janks', {
+    name: 'count',
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('kb', {
+    name: 'sizeInBytes',
+    conversionFactor: 1024,
+    // Less memory usage is better.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('lines', {
+    name: 'count',
+    // More test coverage is better.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('mWh', {
+    name: 'energyInJoules',
+    conversionFactor: 3.6,
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('milliseconds', {
+    name: 'timeDurationInMs',
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('milliseconds-per-frame', {
+    name: 'timeDurationInMs',
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
   LEGACY_UNIT_INFO.set('minutes', {
     name: 'timeDurationInMs',
     conversionFactor: 60e3,
+    // Used for NaCl build time.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
   });
-  LEGACY_UNIT_INFO.set('mips', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('mpixels_sec', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('ms', {name: 'timeDurationInMs'});
-  LEGACY_UNIT_INFO.set('mtri_sec', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('mvtx_sec', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('objects (bigger is better)', {name: 'count'});
-  LEGACY_UNIT_INFO.set('packets', {name: 'count'});
-  LEGACY_UNIT_INFO.set('percent', {name: 'normalizedPercentage'});
-  LEGACY_UNIT_INFO.set('points', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('ports', {name: 'count'});
-  LEGACY_UNIT_INFO.set('reduction%', {name: 'normalizedPercentage'});
-  LEGACY_UNIT_INFO.set('relocs', {name: 'count'});
-  LEGACY_UNIT_INFO.set('runs/s', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('runs_per_s', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('runs_per_second', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('score (bigger is better)', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('score', {name: 'unitlessNumber'});
-  LEGACY_UNIT_INFO.set('score_(bigger_is_better)', {name: 'unitlessNumber'});
+  LEGACY_UNIT_INFO.set('mips', {
+    name: 'unitlessNumber',
+    // More instructions processed per time unit.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('mpixels_sec', {
+    name: 'unitlessNumber',
+    // More pixels processed per time unit.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('ms', {
+    name: 'timeDurationInMs',
+    // Used in many Telemetry measurements. Fewer ms of time means faster.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('mtri_sec', {
+    name: 'unitlessNumber',
+    // More triangles processed per time unit.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('mvtx_sec', {
+    name: 'unitlessNumber',
+    // More vertices processed per time unit.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('objects (bigger is better)', {
+    name: 'count',
+    // Used in spaceport benchmark.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('packets', {
+    name: 'count',
+    // Monitors how many packets we use to accomplish something.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('percent', {
+    name: 'normalizedPercentage',
+    // Synonym for %, used in memory metric for percent fragmentation.
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('points', {
+    name: 'unitlessNumber',
+    // Synonym for score, used in ChromeOS touchpad tests.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('ports', {
+    name: 'count',
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('reduction%', {
+    name: 'normalizedPercentage',
+    // Used in draw_property measurement to indicate relative improvement.
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('relocs', {
+    name: 'count',
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('runs/s', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('runs_per_s', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('runs_per_second', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('score (bigger is better)', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('score', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
+  LEGACY_UNIT_INFO.set('score_(bigger_is_better)', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
   LEGACY_UNIT_INFO.set('seconds', {
     name: 'timeDurationInMs',
     conversionFactor: 1e3,
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
   });
-  LEGACY_UNIT_INFO.set('tokens/s', {name: 'unitlessNumber'});
+  LEGACY_UNIT_INFO.set('tokens/s', {
+    name: 'unitlessNumber',
+    defaultImprovementDirection: tr.b.ImprovementDirection.BIGGER_IS_BETTER,
+  });
   LEGACY_UNIT_INFO.set('us', {
     name: 'timeDurationInMs',
     conversionFactor: 1e-3,
+    defaultImprovementDirection: tr.b.ImprovementDirection.SMALLER_IS_BETTER,
   });
 
   return {