Simplify TimeRange class

Introduce getters and argument type

Bug: 311642700
Flag: EXEMPT EXEMPT
Test: npm run test:unit:ci
Change-Id: Id7d797eef99fc1aa11eb5c88c211498287c18760

Change-Id: I9f893f5362d105137ab34cca61617ded09d6e986
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component.ts
index b0f3eb5..0f38bb4 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/default_timeline_row_component.ts
@@ -150,20 +150,20 @@
   }
 
   private getXPosOf(entry: Timestamp): number {
-    const start = assertDefined(this.selectionRange).from.getValueNs();
-    const end = assertDefined(this.selectionRange).to.getValueNs();
+    const start = assertDefined(this.selectionRange).startNs;
+    const end = assertDefined(this.selectionRange).endNs;
 
     return Number(
-      (BigInt(this.getAvailableWidth()) * (entry.getValueNs() - start)) /
-        (end - start),
+      (BigInt(this.getAvailableWidth()) * BigInt(entry.getValueNs() - start)) /
+        BigInt(end - start),
     );
   }
 
   private getTimestampOf(x: number): Timestamp {
-    const start = assertDefined(this.selectionRange).from.getValueNs();
-    const end = assertDefined(this.selectionRange).to.getValueNs();
+    const start = assertDefined(this.selectionRange).startNs;
+    const end = assertDefined(this.selectionRange).endNs;
     const ts =
-      (BigInt(Math.floor(x)) * (end - start)) /
+      (BigInt(Math.floor(x)) * BigInt(end - start)) /
         BigInt(this.getAvailableWidth()) +
       start;
     return assertDefined(this.timestampConverter).makeTimestampFromNs(ts);
diff --git a/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component.ts b/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component.ts
index 6bb8f42..9cec60c 100644
--- a/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component.ts
+++ b/tools/winscope/src/app/components/timeline/expanded-timeline/transition_timeline_component.ts
@@ -176,8 +176,8 @@
   }
 
   private getXPosOf(entry: Timestamp): number {
-    const start = assertDefined(this.selectionRange).from.getValueNs();
-    const end = assertDefined(this.selectionRange).to.getValueNs();
+    const start = assertDefined(this.selectionRange).startNs;
+    const end = assertDefined(this.selectionRange).endNs;
 
     return Number(
       (BigInt(this.getAvailableWidth()) * (entry.getValueNs() - start)) /
@@ -191,8 +191,8 @@
     rowToUse: number,
   ): Rect {
     const xPosStart = this.getXPosOf(start);
-    const selectionStart = assertDefined(this.selectionRange).from.getValueNs();
-    const selectionEnd = assertDefined(this.selectionRange).to.getValueNs();
+    const selectionStart = assertDefined(this.selectionRange).startNs;
+    const selectionEnd = assertDefined(this.selectionRange).endNs;
 
     const borderPadding = 5;
     let totalRowHeight =
@@ -211,8 +211,8 @@
     const width = Math.max(
       Number(
         (BigInt(this.getAvailableWidth()) *
-          (end.getValueNs() - start.getValueNs())) /
-          (selectionEnd - selectionStart),
+          BigInt(end.getValueNs() - start.getValueNs())) /
+          BigInt(selectionEnd - selectionStart),
       ),
       rowHeight,
     );
@@ -269,11 +269,11 @@
       }
 
       let rowToUse = 0;
-      while ((rowAvailableFrom[rowToUse] ?? 0n) > timeRange.from.getValueNs()) {
+      while ((rowAvailableFrom[rowToUse] ?? 0n) > timeRange.startNs) {
         rowToUse++;
       }
 
-      rowAvailableFrom[rowToUse] = timeRange.to.getValueNs();
+      rowAvailableFrom[rowToUse] = timeRange.endNs;
 
       if (rowToUse + 1 > this.maxRowsRequires) {
         this.maxRowsRequires = rowToUse + 1;
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/mini_timeline_component.ts b/tools/winscope/src/app/components/timeline/mini-timeline/mini_timeline_component.ts
index 882462a..5bb342d 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/mini_timeline_component.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/mini_timeline_component.ts
@@ -515,22 +515,18 @@
     );
     const shiftAmount = transformer
       .untransform(usableRange.from + step)
-      .minus(zoomRange.from.getValueNs());
+      .minus(zoomRange.startNs);
 
-    let newFrom = zoomRange.from.add(shiftAmount.getValueNs());
-    let newTo = zoomRange.to.add(shiftAmount.getValueNs());
+    let newFrom = zoomRange.from.add(shiftAmount);
+    let newTo = zoomRange.to.add(shiftAmount);
 
-    if (newFrom.getValueNs() < fullRange.from.getValueNs()) {
-      newTo = newTo.add(
-        fullRange.from.minus(newFrom.getValueNs()).getValueNs(),
-      );
+    if (newFrom.getValueNs() < fullRange.startNs) {
+      newTo = newTo.add(fullRange.from.minus(newFrom));
       newFrom = fullRange.from;
     }
 
-    if (newTo.getValueNs() > fullRange.to.getValueNs()) {
-      newFrom = newFrom.minus(
-        newTo.minus(fullRange.to.getValueNs()).getValueNs(),
-      );
+    if (newTo.getValueNs() > fullRange.endNs) {
+      newFrom = newFrom.minus(newTo.minus(fullRange.to));
       newTo = fullRange.to;
     }
 
@@ -553,16 +549,14 @@
     const timelineData = assertDefined(this.timelineData);
     const fullRange = timelineData.getFullTimeRange();
     const currentZoomRange = timelineData.getZoomRange();
-    const currentZoomWidth = currentZoomRange.to.minus(
-      currentZoomRange.from.getValueNs(),
-    );
+    const currentZoomWidth = currentZoomRange.to.minus(currentZoomRange.from);
     const zoomToWidth = currentZoomWidth
       .times(zoomRatio.nominator)
       .div(zoomRatio.denominator);
 
     const cursorPosition = this.currentTracePosition?.timestamp;
     const currentMiddle = currentZoomRange.from
-      .add(currentZoomRange.to.getValueNs())
+      .add(currentZoomRange.to)
       .div(2n);
 
     let newFrom: Timestamp;
@@ -579,32 +573,25 @@
 
     newFrom = zoomTowards.minus(
       zoomToWidth
-        .times(
-          zoomTowards.minus(currentZoomRange.from.getValueNs()).getValueNs(),
-        )
-        .div(currentZoomWidth.getValueNs())
-        .getValueNs(),
+        .times(zoomTowards.minus(currentZoomRange.from))
+        .div(currentZoomWidth),
     );
 
     newTo = zoomTowards.add(
       zoomToWidth
-        .times(currentZoomRange.to.minus(zoomTowards.getValueNs()).getValueNs())
-        .div(currentZoomWidth.getValueNs())
-        .getValueNs(),
+        .times(currentZoomRange.to.minus(zoomTowards))
+        .div(currentZoomWidth),
     );
 
-    if (newFrom.getValueNs() < fullRange.from.getValueNs()) {
-      newTo = TimestampUtils.min(
-        fullRange.to,
-        newFrom.add(zoomToWidth.getValueNs()),
-      );
+    if (newFrom.getValueNs() < fullRange.startNs) {
+      newTo = TimestampUtils.min(fullRange.to, newFrom.add(zoomToWidth));
       newFrom = fullRange.from;
     }
 
-    if (newTo.getValueNs() > fullRange.to.getValueNs()) {
+    if (newTo.getValueNs() > fullRange.endNs) {
       newFrom = TimestampUtils.max(
         fullRange.from,
-        fullRange.to.minus(zoomToWidth.getValueNs()),
+        fullRange.to.minus(zoomToWidth),
       );
       newTo = fullRange.to;
     }
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/mini_timeline_component_test.ts b/tools/winscope/src/app/components/timeline/mini-timeline/mini_timeline_component_test.ts
index 1f5ef0f..4c7b00e 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/mini_timeline_component_test.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/mini_timeline_component_test.ts
@@ -284,14 +284,14 @@
 
     dom.findAndClick(zoomOutSelector);
     let finalZoom = timelineData.getZoomRange();
-    expect(finalZoom.from.getValueNs()).toEqual(initialZoom.from.getValueNs());
-    expect(finalZoom.to.getValueNs()).toEqual(initialZoom.to.getValueNs());
+    expect(finalZoom.startNs).toEqual(initialZoom.startNs);
+    expect(finalZoom.endNs).toEqual(initialZoom.endNs);
 
     setCanvasZeroXOffset();
     zoomOutByScrollWheel();
     finalZoom = timelineData.getZoomRange();
-    expect(finalZoom.from.getValueNs()).toEqual(initialZoom.from.getValueNs());
-    expect(finalZoom.to.getValueNs()).toEqual(initialZoom.to.getValueNs());
+    expect(finalZoom.startNs).toEqual(initialZoom.startNs);
+    expect(finalZoom.endNs).toEqual(initialZoom.endNs);
   });
 
   it('zooms in/out with scroll wheel', () => {
@@ -433,12 +433,9 @@
         new KeyboardEvent('keydown', {code: KeyboardEventCode.D}),
       );
       const zoomRange = timelineData.getZoomRange();
-      const increase =
-        zoomRange.from.getValueNs() - initialZoom.from.getValueNs();
+      const increase = zoomRange.startNs - initialZoom.startNs;
       expect(increase).toBeGreaterThan(0);
-      expect(zoomRange.to.getValueNs()).toEqual(
-        initialZoom.to.getValueNs() + increase,
-      );
+      expect(zoomRange.endNs).toEqual(initialZoom.endNs + increase);
     }
 
     // cannot move past end of trace
@@ -453,12 +450,9 @@
         new KeyboardEvent('keydown', {code: KeyboardEventCode.A}),
       );
       const zoomRange = timelineData.getZoomRange();
-      const decrease =
-        finalZoom.from.getValueNs() - zoomRange.from.getValueNs();
+      const decrease = finalZoom.startNs - zoomRange.startNs;
       expect(decrease).toBeGreaterThan(0);
-      expect(zoomRange.to.getValueNs()).toEqual(
-        finalZoom.to.getValueNs() - decrease,
-      );
+      expect(zoomRange.endNs).toEqual(finalZoom.endNs - decrease);
     }
 
     // cannot move before start of trace
@@ -693,12 +687,10 @@
     smallerRange: TimeRange,
   ) {
     expect(biggerRange).not.toBe(smallerRange);
-    expect(smallerRange.from.getValueNs()).toBeGreaterThanOrEqual(
-      Number(biggerRange.from.getValueNs()),
+    expect(smallerRange.startNs).toBeGreaterThanOrEqual(
+      Number(biggerRange.startNs),
     );
-    expect(smallerRange.to.getValueNs()).toBeLessThanOrEqual(
-      Number(biggerRange.to.getValueNs()),
-    );
+    expect(smallerRange.endNs).toBeLessThanOrEqual(Number(biggerRange.endNs));
   }
 
   function zoomInByKeyW() {
@@ -759,12 +751,11 @@
       currentZoom = zoomedIn;
 
       const zoomedInTimestamp = zoomedIn.from.add(
-        (zoomedIn.to.minus(zoomedIn.from.getValueNs()).getValueNs() *
-          ratioNom) /
+        (zoomedIn.to.minus(zoomedIn.startNs).getValueNs() * ratioNom) /
           ratioDenom,
       );
       expect(
-        Math.abs(Number(zoomedInTimestamp.minus(zoomOnTimestamp.getValueNs()))),
+        Math.abs(Number(zoomedInTimestamp.minus(zoomOnTimestamp))),
       ).toBeLessThanOrEqual(5);
     }
     for (let i = 0; i < 4; i++) {
@@ -775,14 +766,11 @@
       currentZoom = zoomedOut;
 
       const zoomedOutTimestamp = zoomedOut.from.add(
-        (zoomedOut.to.minus(zoomedOut.from.getValueNs()).getValueNs() *
-          ratioNom) /
+        (zoomedOut.to.minus(zoomedOut.startNs).getValueNs() * ratioNom) /
           ratioDenom,
       );
       expect(
-        Math.abs(
-          Number(zoomedOutTimestamp.minus(zoomOnTimestamp.getValueNs())),
-        ),
+        Math.abs(Number(zoomedOutTimestamp.minus(zoomOnTimestamp))),
       ).toBeLessThanOrEqual(5);
     }
   }
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/slider_component.ts b/tools/winscope/src/app/components/timeline/mini-timeline/slider_component.ts
index deb6e09..014986f 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/slider_component.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/slider_component.ts
@@ -166,7 +166,7 @@
   syncDragPositionTo(zoomRange: TimeRange) {
     this.sliderWidth = this.computeSliderWidth();
     const middleOfZoomRange = zoomRange.from.add(
-      zoomRange.to.minus(zoomRange.from.getValueNs()).div(2n).getValueNs(),
+      zoomRange.to.minus(zoomRange.from).div(2n).getValueNs(),
     );
 
     this.dragPosition = {
@@ -248,14 +248,12 @@
     // Calculation to adjust for min width slider
     const from = this.getTransformer()
       .untransform(newX + this.sliderWidth / 2)
-      .minus(
-        zoomRange.to.minus(zoomRange.from.getValueNs()).div(2n).getValueNs(),
-      );
+      .minus(zoomRange.to.minus(zoomRange.from).div(2n));
 
     const to = assertDefined(this.timestampConverter).makeTimestampFromNs(
       from.getValueNs() +
-        (assertDefined(this.zoomRange).to.getValueNs() -
-          assertDefined(this.zoomRange).from.getValueNs()),
+        (assertDefined(this.zoomRange).endNs -
+          assertDefined(this.zoomRange).startNs),
     );
 
     this.onZoomChanged.emit(new TimeRange(from, to));
@@ -272,10 +270,10 @@
     const listener = (event: MouseEvent) => {
       const movedX = event.pageX - startPos;
       let from = this.getTransformer().untransform(startOffset + movedX);
-      if (from.getValueNs() < assertDefined(this.fullRange).from.getValueNs()) {
+      if (from.getValueNs() < assertDefined(this.fullRange).startNs) {
         from = assertDefined(this.fullRange).from;
       }
-      if (from.getValueNs() > assertDefined(this.zoomRange).to.getValueNs()) {
+      if (from.getValueNs() > assertDefined(this.zoomRange).endNs) {
         from = assertDefined(this.zoomRange).to;
       }
       const to = assertDefined(this.zoomRange).to;
@@ -303,10 +301,10 @@
       const movedX = event.pageX - startPos;
       const from = assertDefined(this.zoomRange).from;
       let to = this.getTransformer().untransform(startOffset + movedX);
-      if (to.getValueNs() > assertDefined(this.fullRange).to.getValueNs()) {
+      if (to.getValueNs() > assertDefined(this.fullRange).endNs) {
         to = assertDefined(this.fullRange).to;
       }
-      if (to.getValueNs() < assertDefined(this.zoomRange).from.getValueNs()) {
+      if (to.getValueNs() < assertDefined(this.zoomRange).startNs) {
         to = assertDefined(this.zoomRange).from;
       }
 
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/slider_component_test.ts b/tools/winscope/src/app/components/timeline/mini-timeline/slider_component_test.ts
index 5f9e6f2..9db32b1 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/slider_component_test.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/slider_component_test.ts
@@ -182,9 +182,9 @@
     const finalZoom = assertDefined<TimeRange>(lastZoomUpdate);
     expect(finalZoom.from).not.toEqual(initialZoom.from);
     expect(finalZoom.to).not.toEqual(initialZoom.to);
-    expect(
-      finalZoom.to.minus(finalZoom.from.getValueNs()).getValueNs(),
-    ).toEqual(initialZoom.to.minus(initialZoom.from.getValueNs()).getValueNs());
+    expect(finalZoom.to.minus(finalZoom.from).getValueNs()).toEqual(
+      initialZoom.to.minus(initialZoom.from).getValueNs(),
+    );
   });
 
   it('moving slider left pointer around updates zoom', fakeAsync(() => {
@@ -252,8 +252,8 @@
     expect(zoomChangedSpy).toHaveBeenCalled();
 
     const finalZoom = assertDefined<TimeRange>(lastZoomUpdate);
-    expect(finalZoom.from.getValueNs()).toEqual(initialZoom.from.getValueNs());
-    expect(finalZoom.to.getValueNs()).toEqual(initialZoom.to.getValueNs());
+    expect(finalZoom.startNs).toEqual(initialZoom.startNs);
+    expect(finalZoom.endNs).toEqual(initialZoom.endNs);
     discardPeriodicTasks();
   }));
 
@@ -276,8 +276,8 @@
     expect(zoomChangedSpy).toHaveBeenCalled();
 
     const finalZoom = assertDefined<TimeRange>(lastZoomUpdate);
-    expect(finalZoom.from.getValueNs()).toEqual(initialZoom.from.getValueNs());
-    expect(finalZoom.to.getValueNs()).toEqual(initialZoom.to.getValueNs());
+    expect(finalZoom.startNs).toEqual(initialZoom.startNs);
+    expect(finalZoom.endNs).toEqual(initialZoom.endNs);
     discardPeriodicTasks();
   }));
 
@@ -300,8 +300,8 @@
     expect(zoomChangedSpy).toHaveBeenCalled();
 
     const finalZoom = assertDefined<TimeRange>(lastZoomUpdate);
-    expect(finalZoom.from.getValueNs()).toEqual(initialZoom.from.getValueNs());
-    expect(finalZoom.to.getValueNs()).toEqual(initialZoom.to.getValueNs());
+    expect(finalZoom.startNs).toEqual(initialZoom.startNs);
+    expect(finalZoom.endNs).toEqual(initialZoom.endNs);
     discardPeriodicTasks();
   }));
 
@@ -324,8 +324,8 @@
     expect(zoomChangedSpy).toHaveBeenCalled();
 
     const finalZoom = assertDefined<TimeRange>(lastZoomUpdate);
-    expect(finalZoom.from.getValueNs()).toEqual(initialZoom.from.getValueNs());
-    expect(finalZoom.to.getValueNs()).toEqual(initialZoom.to.getValueNs());
+    expect(finalZoom.startNs).toEqual(initialZoom.startNs);
+    expect(finalZoom.endNs).toEqual(initialZoom.endNs);
     discardPeriodicTasks();
   }));
 
@@ -348,8 +348,8 @@
     expect(zoomChangedSpy).toHaveBeenCalled();
 
     const finalZoom = assertDefined<TimeRange>(lastZoomUpdate);
-    expect(finalZoom.from.getValueNs()).toEqual(initialZoom.from.getValueNs());
-    expect(finalZoom.to.getValueNs()).toEqual(initialZoom.to.getValueNs());
+    expect(finalZoom.startNs).toEqual(initialZoom.startNs);
+    expect(finalZoom.endNs).toEqual(initialZoom.endNs);
   });
 
   function checkVisible(element: HTMLElement) {
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/transformer.ts b/tools/winscope/src/app/components/timeline/mini-timeline/transformer.ts
index 874cada..64ae7c9 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/transformer.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/transformer.ts
@@ -33,14 +33,13 @@
     private canvasPosRange: Segment,
     private timestampConverter: ComponentTimestampConverter,
   ) {
-    this.tsRangeWidth =
-      this.tsRange.to.getValueNs() - this.tsRange.from.getValueNs();
+    this.tsRangeWidth = BigInt(this.tsRange.endNs - this.tsRange.startNs);
     // Needs to be a whole number to be compatible with bigints
     this.canvasWidth = Math.round(
       this.canvasPosRange.to - this.canvasPosRange.from,
     );
 
-    this.tsOffset = this.tsRange.from.getValueNs();
+    this.tsOffset = this.tsRange.startNs;
     // Needs to be a whole number to be compatible with bigints
     this.canvasOffset = this.canvasPosRange.from;
   }
diff --git a/tools/winscope/src/app/components/timeline/mini-timeline/transformer_test.ts b/tools/winscope/src/app/components/timeline/mini-timeline/transformer_test.ts
index be4675f..cde3cc8 100644
--- a/tools/winscope/src/app/components/timeline/mini-timeline/transformer_test.ts
+++ b/tools/winscope/src/app/components/timeline/mini-timeline/transformer_test.ts
@@ -34,9 +34,9 @@
       TimestampConverterUtils.TIMESTAMP_CONVERTER,
     );
 
-    const rangeStart = fromRange.from.getValueNs();
-    const rangeEnd = fromRange.to.getValueNs();
-    const range = fromRange.to.getValueNs() - fromRange.from.getValueNs();
+    const rangeStart = fromRange.startNs;
+    const rangeEnd = fromRange.endNs;
+    const range = fromRange.endNs - fromRange.startNs;
 
     expect(transformer.transform(fromRange.from)).toBe(toRange.from);
     expect(transformer.transform(fromRange.to)).toBe(toRange.to);
@@ -84,14 +84,14 @@
       TimestampConverterUtils.TIMESTAMP_CONVERTER,
     );
 
-    const rangeStart = fromRange.from.getValueNs();
-    const range = fromRange.to.getValueNs() - fromRange.from.getValueNs();
+    const rangeStart = fromRange.startNs;
+    const range = fromRange.endNs - fromRange.startNs;
 
     expect(transformer.untransform(toRange.from).getValueNs()).toBe(
-      fromRange.from.getValueNs(),
+      fromRange.startNs,
     );
     expect(transformer.untransform(toRange.to).getValueNs()).toBe(
-      fromRange.to.getValueNs(),
+      fromRange.endNs,
     );
 
     expect(
diff --git a/tools/winscope/src/app/components/timeline/timeline_component.ts b/tools/winscope/src/app/components/timeline/timeline_component.ts
index 9e5cb68..73304b0 100644
--- a/tools/winscope/src/app/components/timeline/timeline_component.ts
+++ b/tools/winscope/src/app/components/timeline/timeline_component.ts
@@ -977,7 +977,7 @@
         range.containsTimestamp(bookmark),
       );
     }
-    const clickedNs = (range.from.getValueNs() + range.to.getValueNs()) / 2n;
+    const clickedNs = (range.startNs + range.endNs) / 2n;
     if (rangeContainsBookmark) {
       const closestBookmark = this.bookmarks.reduce((prev, curr) => {
         if (clickedNs - curr.getValueNs() < 0) return prev;
diff --git a/tools/winscope/src/app/components/timeline/timeline_utils.ts b/tools/winscope/src/app/components/timeline/timeline_utils.ts
index aac4663..d1680bb 100644
--- a/tools/winscope/src/app/components/timeline/timeline_utils.ts
+++ b/tools/winscope/src/app/components/timeline/timeline_utils.ts
@@ -91,8 +91,8 @@
     return undefined;
   }
 
-  const timeRangeMin = fullTimeRange.from.getValueNs();
-  const timeRangeMax = fullTimeRange.to.getValueNs();
+  const timeRangeMin = fullTimeRange.startNs;
+  const timeRangeMax = fullTimeRange.endNs;
 
   if (
     finishOrAbortTimestamp &&
diff --git a/tools/winscope/src/app/loaded_parsers.ts b/tools/winscope/src/app/loaded_parsers.ts
index fca7a6f..8c33c4a 100644
--- a/tools/winscope/src/app/loaded_parsers.ts
+++ b/tools/winscope/src/app/loaded_parsers.ts
@@ -342,7 +342,7 @@
       timestamps = assertDefined(timestamps);
 
       const endTimestamp = timestamps[timestamps.length - 1];
-      const isOldData = endTimestamp.getValueNs() <= timeGap.from.getValueNs();
+      const isOldData = endTimestamp.getValueNs() <= timeGap.startNs;
       if (isOldData) {
         UserNotifier.add(new TraceHasOldData(file.getDescriptor(), timeGap));
         return false;
@@ -469,12 +469,12 @@
   ): TimeRange | undefined {
     const rangesSortedByEnd = ranges
       .slice()
-      .sort((a, b) => (a.to.getValueNs() < b.to.getValueNs() ? -1 : +1));
+      .sort((a, b) => (a.endNs < b.endNs ? -1 : +1));
 
     for (let i = rangesSortedByEnd.length - 2; i >= 0; --i) {
       const curr = rangesSortedByEnd[i];
       const next = rangesSortedByEnd[i + 1];
-      const gap = next.from.getValueNs() - curr.to.getValueNs();
+      const gap = next.startNs - curr.endNs;
       if (gap > LoadedParsers.MAX_ALLOWED_TIME_GAP_BETWEEN_TRACES_NS) {
         return new TimeRange(curr.to, next.from);
       }
diff --git a/tools/winscope/src/app/mediator_test.ts b/tools/winscope/src/app/mediator_test.ts
index 2d79d8e..ac6fead 100644
--- a/tools/winscope/src/app/mediator_test.ts
+++ b/tools/winscope/src/app/mediator_test.ts
@@ -490,7 +490,7 @@
 
     // notify position
     resetSpyCalls();
-    const finalTimestampNs = timelineData.getFullTimeRange().to.getValueNs();
+    const finalTimestampNs = timelineData.getFullTimeRange().endNs;
     const timestamp =
       TimestampConverterUtils.makeRealTimestamp(finalTimestampNs);
     const position = TracePosition.fromTimestamp(timestamp);
diff --git a/tools/winscope/src/app/timeline_data.ts b/tools/winscope/src/app/timeline_data.ts
index d98372e..d353168 100644
--- a/tools/winscope/src/app/timeline_data.ts
+++ b/tools/winscope/src/app/timeline_data.ts
@@ -206,10 +206,8 @@
 
     if (
       this.lastReturnedFullTimeRange === undefined ||
-      this.lastReturnedFullTimeRange.from.getValueNs() !==
-        fullTimeRange.from.getValueNs() ||
-      this.lastReturnedFullTimeRange.to.getValueNs() !==
-        fullTimeRange.to.getValueNs()
+      this.lastReturnedFullTimeRange.startNs !== fullTimeRange.startNs ||
+      this.lastReturnedFullTimeRange.endNs !== fullTimeRange.endNs
     ) {
       this.lastReturnedFullTimeRange = fullTimeRange;
     }
diff --git a/tools/winscope/src/common/time/time.ts b/tools/winscope/src/common/time/time.ts
index 5a5cd30..887f9f6 100644
--- a/tools/winscope/src/common/time/time.ts
+++ b/tools/winscope/src/common/time/time.ts
@@ -23,12 +23,30 @@
  * A class representing a time range.
  */
 export class TimeRange {
+  /**
+   * @param from The start of the time range.
+   * @param to The end of the time range.
+   */
   constructor(
     readonly from: Timestamp,
     readonly to: Timestamp,
   ) {}
 
   /**
+   * Gets the start of the time range in nanoseconds.
+   */
+  get startNs(): bigint {
+    return this.from.getValueNs();
+  }
+
+  /**
+   * Gets the end of the time range in nanoseconds.
+   */
+  get endNs(): bigint {
+    return this.to.getValueNs();
+  }
+
+  /**
    * Checks if a timestamp is within the time range.
    *
    * @param ts The timestamp to check.
@@ -78,6 +96,10 @@
   private readonly utcValueNs: bigint;
   private readonly formatter: TimestampFormatter;
 
+  /**
+   * @param valueNs The value of the timestamp in nanoseconds.
+   * @param formatter The formatter to use for formatting the timestamp.
+   */
   constructor(valueNs: bigint, formatter: TimestampFormatter) {
     this.utcValueNs = valueNs;
     this.formatter = formatter;
@@ -109,8 +131,7 @@
    */
   in(range: TimeRange): boolean {
     return (
-      range.from.getValueNs() <= this.getValueNs() &&
-      this.getValueNs() <= range.to.getValueNs()
+      range.startNs <= this.getValueNs() && this.getValueNs() <= range.endNs
     );
   }
 
@@ -120,7 +141,14 @@
    * @param n The value to add.
    * @return A new timestamp with the added value.
    */
-  add(n: bigint): Timestamp {
+  add(other: bigint | Timestamp): Timestamp {
+    let n: bigint;
+    if (other instanceof Timestamp) {
+      n = other.getValueNs();
+    } else {
+      n = other;
+    }
+
     return new Timestamp(this.getValueNs() + n, this.formatter);
   }
 
@@ -130,7 +158,13 @@
    * @param n The value to subtract.
    * @return A new timestamp with the subtracted value.
    */
-  minus(n: bigint): Timestamp {
+  minus(other: bigint | Timestamp): Timestamp {
+    let n: bigint;
+    if (other instanceof Timestamp) {
+      n = other.getValueNs();
+    } else {
+      n = other;
+    }
     return new Timestamp(this.getValueNs() - n, this.formatter);
   }
 
@@ -140,7 +174,13 @@
    * @param n The value to multiply by.
    * @return A new timestamp with the multiplied value.
    */
-  times(n: bigint): Timestamp {
+  times(other: bigint | Timestamp): Timestamp {
+    let n: bigint;
+    if (other instanceof Timestamp) {
+      n = other.getValueNs();
+    } else {
+      n = other;
+    }
     return new Timestamp(this.getValueNs() * n, this.formatter);
   }
 
@@ -150,7 +190,13 @@
    * @param n The value to divide by.
    * @return A new timestamp with the divided value.
    */
-  div(n: bigint): Timestamp {
+  div(other: bigint | Timestamp): Timestamp {
+    let n: bigint;
+    if (other instanceof Timestamp) {
+      n = other.getValueNs();
+    } else {
+      n = other;
+    }
     return new Timestamp(this.getValueNs() / n, this.formatter);
   }
 
diff --git a/tools/winscope/src/messaging/user_warnings.ts b/tools/winscope/src/messaging/user_warnings.ts
index 97e1d5b..121811f 100644
--- a/tools/winscope/src/messaging/user_warnings.ts
+++ b/tools/winscope/src/messaging/user_warnings.ts
@@ -102,9 +102,7 @@
 
   getMessage(): string {
     const elapsedTime = this.timeGap
-      ? new TimeDuration(
-          this.timeGap.to.getValueNs() - this.timeGap.from.getValueNs(),
-        )
+      ? new TimeDuration(this.timeGap.endNs - this.timeGap.startNs)
       : undefined;
     return (
       `${this.descriptor}: discarded because data is old` +