Zoom mini-timeline to selection area

Test: try it out in Winscope
Change-Id: I3fdcd501b9f7867f6302ea2dc2ab9a8303c87b80
diff --git a/tools/winscope/src/app/components/timeline/mini_canvas_drawer.ts b/tools/winscope/src/app/components/timeline/mini_canvas_drawer.ts
index 14c6b77..cb6e1cd 100644
--- a/tools/winscope/src/app/components/timeline/mini_canvas_drawer.ts
+++ b/tools/winscope/src/app/components/timeline/mini_canvas_drawer.ts
@@ -31,11 +31,13 @@
     public fullRange: TimeRange,
     public selectedPosition: Timestamp,
     public selection: TimeRange,
+    public zoomRange: TimeRange,
     public traces: Traces
   ) {}
 
   transform(mapToRange: Segment): MiniCanvasDrawerData {
-    const transformer = new Transformer(this.fullRange, mapToRange);
+    const transformer = new Transformer(this.zoomRange, mapToRange);
+
     return new MiniCanvasDrawerData(
       transformer.transform(this.selectedPosition),
       {
@@ -86,7 +88,7 @@
 
     this.fromOffset = this.fromRange.from.getValueNs();
     // Needs to be a whole number to be compatible with bigints
-    this.toOffset = Math.round(this.toRange.from);
+    this.toOffset = this.toRange.from;
   }
 
   transform(x: Timestamp): number {
@@ -159,7 +161,7 @@
     };
   }
 
-  get input() {
+  get input(): MiniCanvasDrawerData {
     return this.inputGetter().transform(this.usableRange);
   }
 
@@ -169,6 +171,7 @@
     private onPointerPositionDragging: (pos: Timestamp) => void,
     private onPointerPositionChanged: (pos: Timestamp) => void,
     private onSelectionChanged: (selection: TimeRange) => void,
+    private onZoomChanged: (zoom: TimeRange) => void,
     private onUnhandledClick: (pos: Timestamp) => void
   ) {
     const ctx = canvas.getContext('2d');
@@ -235,6 +238,19 @@
       });
     };
 
+    const onLeftZoomChanged = (x: number) => {
+      this.onZoomChanged({
+        from: this.input.transformer.untransform(x),
+        to: this.inputGetter().zoomRange.to,
+      });
+    }
+    const onRightZoomChanged = (x: number) => {
+      this.onZoomChanged({
+        from: this.inputGetter().zoomRange.from,
+        to: this.input.transformer.untransform(x),
+      });
+    }
+
     const barWidth = 6;
     const selectorArrowWidth = this.innerHeight / 12;
     const selectorArrowHeight = selectorArrowWidth * 2;
@@ -255,7 +271,10 @@
       },
       focusSelectorDrawConfig,
       onLeftSelectionChanged,
-      onLeftSelectionChanged,
+      (x: number) => {
+        onLeftSelectionChanged(x);
+        onLeftZoomChanged(x);
+      },
       () => {
         return {
           from: this.usableRange.from,
@@ -279,7 +298,10 @@
       },
       focusSelectorDrawConfig,
       onRightSelectionChanged,
-      onRightSelectionChanged,
+      (x: number) => {
+        onRightSelectionChanged(x);
+        onRightZoomChanged(x);
+      },
       () => {
         return {
           from: this.leftFocusSectionSelector.position + selectorArrowWidth + barWidth,
diff --git a/tools/winscope/src/app/components/timeline/mini_timeline_component.ts b/tools/winscope/src/app/components/timeline/mini_timeline_component.ts
index 2f11e1e..fd24d3f 100644
--- a/tools/winscope/src/app/components/timeline/mini_timeline_component.ts
+++ b/tools/winscope/src/app/components/timeline/mini_timeline_component.ts
@@ -76,15 +76,10 @@
     this.drawer = new MiniCanvasDrawer(
       this.canvas,
       () => this.getMiniCanvasDrawerInput(),
-      (position) => {
-        const timestampType = this.timelineData.getTimestampType()!;
-        this.onSeekTimestampUpdate.emit(position);
-      },
+      (position) => this.onSeekTimestampUpdate.emit(position),
       updateTimestampCallback,
-      (selection) => {
-        const timestampType = this.timelineData.getTimestampType()!;
-        this.timelineData.setSelectionTimeRange(selection);
-      },
+      (selection) => this.timelineData.setSelectionTimeRange(selection),
+      (zoom) => this.timelineData.setZoom(zoom),
       updateTimestampCallback
     );
     this.drawer.draw();
@@ -101,6 +96,7 @@
       this.timelineData.getFullTimeRange(),
       this.currentTracePosition.timestamp,
       this.timelineData.getSelectionTimeRange(),
+      this.timelineData.getZoomRange(),
       this.getTracesToShow()
     );
   }
diff --git a/tools/winscope/src/app/timeline_data.ts b/tools/winscope/src/app/timeline_data.ts
index 7910600..3c29e28 100644
--- a/tools/winscope/src/app/timeline_data.ts
+++ b/tools/winscope/src/app/timeline_data.ts
@@ -38,6 +38,7 @@
   private lastEntry?: TraceEntry<{}>;
   private explicitlySetPosition?: TracePosition;
   private explicitlySetSelection?: TimeRange;
+  private explicitlySetZoomRange?: TimeRange;
   private activeViewTraceTypes: TraceType[] = []; // dependencies of current active view
 
   initialize(traces: Traces, screenRecordingVideo: Blob | undefined) {
@@ -126,6 +127,18 @@
     this.explicitlySetSelection = selection;
   }
 
+  getZoomRange(): TimeRange {
+    if (this.explicitlySetZoomRange === undefined) {
+      return this.getFullTimeRange();
+    } else {
+      return this.explicitlySetZoomRange;
+    }
+  }
+
+  setZoom(zoomRange: TimeRange) {
+    this.explicitlySetZoomRange = zoomRange;
+  }
+
   getTraces(): Traces {
     return this.traces;
   }