<NME> TouchCatcherView.java
<BEF> package org.chromium.latency.walt;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;



public class TouchCatcherView extends View {

    private Paint linePaint = new Paint();
    private ClockManager clockManager;

    public TouchCatcherView(Context context, AttributeSet attrs) {
        super(context, attrs);
        waltDevice = WaltDevice.getInstance(context);
        initialisePaint();
    }

    private void initialisePaint() {
        float density = getResources().getDisplayMetrics().density;
        float lineWidth = 10f * density;
        linePaint.setColor(Color.RED);
        linePaint.setStrokeWidth(lineWidth);
    }

    public static double markerPosition(long t_us) {
        int period = 1000000;  // microseconds
        // Normalized time within period, goes from 0 to 1
        double t = (t_us % period) / (double) period;
        // Triangular wave with amplitude 1
        double x_tri = -1 + 4 * Math.abs(t - 0.5);

        // Apply some smoothing to get rid of the sharp edges of triangular wave.
        // beta is a dimensionless smoothing parameter used below, experimentally derived.
        // Higher value gives less smoothing.
        double beta = 4;
        // Multiply by the smoothing function 1/{1 + exp(b(|x|-1))/(b-1)}
        // This is a Fermi function, modified to have a zero derivative at x = 1.
        double x_smooth = x_tri / (1 + Math.exp(beta*(Math.abs(x_tri)-1))/(beta - 1));
        return x_smooth;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int h = getHeight();
        double normPos = markerPosition(clockManager.micros());
        double amplitude = 0.4; // Of View height
        int pos = (int) (h * (0.5 + amplitude * normPos));
        // Log.i("AnimatedView", "Pos is " + pos);
        int w = getWidth();
        canvas.drawLine(w/3, pos, w*2/3, pos, linePaint);

        // Run every frame
        invalidate();
    }
}

<MSG> Only start animation when test starts

Plus some cleanup.

<DFF> @@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
 package org.chromium.latency.walt;
 
 import android.content.Context;
@@ -13,6 +29,21 @@ public class TouchCatcherView extends View {
 
     private Paint linePaint = new Paint();
     private ClockManager clockManager;
+    private boolean isAnimated = false;
+
+    private double animationAmplitude = 0.4;  // Faction of view height
+    private double lineLength = 0.6;  // Fraction of view width
+    public final int animationPeriod_us = 1000000;
+
+    public void startAnimation() {
+        isAnimated = true;
+        invalidate();
+    }
+
+    public void stopAnimation() {
+        isAnimated = false;
+        invalidate();
+    }
 
     public TouchCatcherView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -23,38 +54,46 @@ public class TouchCatcherView extends View {
     private void initialisePaint() {
         float density = getResources().getDisplayMetrics().density;
         float lineWidth = 10f * density;
-        linePaint.setColor(Color.RED);
+        linePaint.setColor(Color.GREEN);
         linePaint.setStrokeWidth(lineWidth);
     }
 
-    public static double markerPosition(long t_us) {
-        int period = 1000000;  // microseconds
-        // Normalized time within period, goes from 0 to 1
-        double t = (t_us % period) / (double) period;
-        // Triangular wave with amplitude 1
-        double x_tri = -1 + 4 * Math.abs(t - 0.5);
+    public static double markerPosition(long t_us, int period_us) {
+        // Normalized time within a period, goes from 0 to 1
+        double t = (t_us % period_us) / (double) period_us;
 
-        // Apply some smoothing to get rid of the sharp edges of triangular wave.
-        // beta is a dimensionless smoothing parameter used below, experimentally derived.
-        // Higher value gives less smoothing.
+        // Triangular wave with unit amplitude
+        //  1| *               *
+        //   |   *           *   *
+        //   0-----*-------*---|---*-----> t
+        //   |       *   *     1     *
+        // -1|         *               *
+        double y_tri = -1 + 4 * Math.abs(t - 0.5);
+
+        // Apply some smoothing to get a feeling of deceleration and acceleration at the edges.
+        // f(y) = y / {1 + exp(b(|y|-1))/(b-1)}
+        // This is inspired by Fermi function and adjusted to have continuous derivative at extrema.
+        // b = beta is a dimensionless smoothing parameter, value selected by experimentation.
+        // Higher value gives less smoothing = closer to original triangular wave.
         double beta = 4;
-        // Multiply by the smoothing function 1/{1 + exp(b(|x|-1))/(b-1)}
-        // This is a Fermi function, modified to have a zero derivative at x = 1.
-        double x_smooth = x_tri / (1 + Math.exp(beta*(Math.abs(x_tri)-1))/(beta - 1));
-        return x_smooth;
+        double y_smooth = y_tri / (1 + Math.exp(beta*(Math.abs(y_tri)-1))/(beta - 1));
+        return y_smooth;
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
+        if (!isAnimated) return;
 
         int h = getHeight();
-        double normPos = markerPosition(clockManager.micros());
-        double amplitude = 0.4; // Of View height
-        int pos = (int) (h * (0.5 + amplitude * normPos));
+        double normPos = markerPosition(clockManager.micros(), animationPeriod_us);
+        int pos = (int) (h * (0.5 + animationAmplitude * normPos));
         // Log.i("AnimatedView", "Pos is " + pos);
         int w = getWidth();
-        canvas.drawLine(w/3, pos, w*2/3, pos, linePaint);
+
+        int lineStart = (int) (w * (1 - lineLength) / 2);
+        int lineEnd   = (int) (w * (1 + lineLength) / 2);
+        canvas.drawLine(lineStart, pos, lineEnd, pos, linePaint);
 
         // Run every frame
         invalidate();

Only start animation when test starts