perfetto-ui: Persist timespan highlight

The timespan highlight is persisted until the user clicks outside
of the range. This means the user can select individual items inside
the timespan and not lose the highlight.

Also the 'm' key will zoom as well as highlighting the timespan
of the current selection.

See https://goto.google.com/perfetto-multi-selection

Bug:141100137
Change-Id: I5a245e97b30531cec58ad80b622da0e53c41a834
diff --git a/ui/src/frontend/track_panel.ts b/ui/src/frontend/track_panel.ts
index 18ad066..5912c96 100644
--- a/ui/src/frontend/track_panel.ts
+++ b/ui/src/frontend/track_panel.ts
@@ -146,11 +146,18 @@
         attrs.track.onMouseOut();
         globals.rafScheduler.scheduleRedraw();
       },
-      onclick: (e:MouseEvent) => {
+      onclick: (e: MouseEvent) => {
         // If we are selecting a timespan - do not pass the click to the track.
-        const selection = globals.state.currentSelection;
-        if (selection && selection.kind === 'TIMESPAN') return;
-        if (attrs.track.onMouseClick({x: e.layerX, y: e.layerY})) {
+        if (e.shiftKey) return;
+        // If the click is outside of the current timespan, clear it.
+        const clickTime =
+            globals.frontendLocalState.timeScale.pxToTime(e.layerX);
+        if (globals.state.timeSpan !== null &&
+            (clickTime < globals.state.timeSpan.startTs ||
+             clickTime > globals.state.timeSpan.endTs)) {
+          globals.dispatch(Actions.removeTimeSpan({}));
+          e.stopPropagation();
+        } else if (attrs.track.onMouseClick({x: e.layerX, y: e.layerY})) {
           e.stopPropagation();
         }
         globals.rafScheduler.scheduleRedraw();
@@ -249,7 +256,15 @@
                              size.height,
                              `rgb(52,69,150)`);
     }
-
+    if (globals.state.timeSpan !== null) {
+      drawVerticalSelection(
+          ctx,
+          localState.timeScale,
+          globals.state.timeSpan.startTs,
+          globals.state.timeSpan.endTs,
+          size.height,
+          `rgba(0,0,0,0.5)`);
+    }
     if (globals.state.currentSelection !== null) {
       if (globals.state.currentSelection.kind === 'NOTE') {
         const note = globals.state.notes[globals.state.currentSelection.id];
@@ -259,15 +274,6 @@
                                size.height,
                                note.color);
       }
-      if (globals.state.currentSelection.kind === 'TIMESPAN') {
-        drawVerticalSelection(
-            ctx,
-            localState.timeScale,
-            globals.state.currentSelection.startTs,
-            globals.state.currentSelection.endTs,
-            size.height,
-            `rgba(0,0,0,0.5)`);
-      }
       if (globals.state.currentSelection.kind === 'SLICE' &&
           globals.sliceDetails.wakeupTs !== undefined) {
         drawVerticalLineAtTime(