1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.chromium.latency.walt; 18 19 import android.content.Context; 20 import android.graphics.Canvas; 21 import android.graphics.Color; 22 import android.graphics.Paint; 23 import android.util.AttributeSet; 24 import android.view.View; 25 26 27 28 public class TouchCatcherView extends View { 29 30 private Paint linePaint = new Paint(); 31 private WaltDevice waltDevice; 32 private boolean isAnimated = false; 33 34 private double animationAmplitude = 0.4; // Fraction of view height 35 private double lineLength = 0.6; // Fraction of view width 36 public final int animationPeriod_us = 1000000; 37 startAnimation()38 public void startAnimation() { 39 isAnimated = true; 40 invalidate(); 41 } 42 stopAnimation()43 public void stopAnimation() { 44 isAnimated = false; 45 invalidate(); 46 } 47 TouchCatcherView(Context context, AttributeSet attrs)48 public TouchCatcherView(Context context, AttributeSet attrs) { 49 super(context, attrs); 50 waltDevice = WaltDevice.getInstance(context); 51 initialisePaint(); 52 } 53 initialisePaint()54 private void initialisePaint() { 55 float density = getResources().getDisplayMetrics().density; 56 float lineWidth = 10f * density; 57 linePaint.setColor(Color.GREEN); 58 linePaint.setStrokeWidth(lineWidth); 59 } 60 markerPosition(long t_us, int period_us)61 public static double markerPosition(long t_us, int period_us) { 62 // Normalized time within a period, goes from 0 to 1 63 double t = (t_us % period_us) / (double) period_us; 64 65 // Triangular wave with unit amplitude 66 // 1| * * 67 // | * * * 68 // 0-----*-------*---|---*-----> t 69 // | * * 1 * 70 // -1| * * 71 double y_tri = -1 + 4 * Math.abs(t - 0.5); 72 73 // Apply some smoothing to get a feeling of deceleration and acceleration at the edges. 74 // f(y) = y / {1 + exp(b(|y|-1))/(b-1)} 75 // This is inspired by Fermi function and adjusted to have continuous derivative at extrema. 76 // b = beta is a dimensionless smoothing parameter, value selected by experimentation. 77 // Higher value gives less smoothing = closer to original triangular wave. 78 double beta = 4; 79 double y_smooth = y_tri / (1 + Math.exp(beta*(Math.abs(y_tri)-1))/(beta - 1)); 80 return y_smooth; 81 } 82 83 @Override onDraw(Canvas canvas)84 protected void onDraw(Canvas canvas) { 85 super.onDraw(canvas); 86 if (!isAnimated) return; 87 88 int h = getHeight(); 89 double normPos = markerPosition(waltDevice.clock.micros(), animationPeriod_us); 90 int pos = (int) (h * (0.5 + animationAmplitude * normPos)); 91 // Log.i("AnimatedView", "Pos is " + pos); 92 int w = getWidth(); 93 94 int lineStart = (int) (w * (1 - lineLength) / 2); 95 int lineEnd = (int) (w * (1 + lineLength) / 2); 96 canvas.drawLine(lineStart, pos, lineEnd, pos, linePaint); 97 98 // Run every frame 99 invalidate(); 100 } 101 } 102