Home | History | Annotate | Download | only in touchlatency
      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 com.prefabulated.touchlatency;
     18 
     19 import android.app.Activity;
     20 import android.content.Context;
     21 import android.graphics.Canvas;
     22 import android.graphics.Color;
     23 import android.graphics.Paint;
     24 import android.os.CountDownTimer;
     25 import android.os.Bundle;
     26 import android.text.method.Touch;
     27 import android.util.AttributeSet;
     28 import android.util.Log;
     29 import android.view.Menu;
     30 import android.view.MenuItem;
     31 import android.view.MotionEvent;
     32 import android.view.View;
     33 
     34 import java.util.ArrayList;
     35 import java.util.Collections;
     36 
     37 class TouchLatencyView extends View implements View.OnTouchListener {
     38     private static final String LOG_TAG = "TouchLatency";
     39     private static final int BACKGROUND_COLOR = 0xFF400080;
     40     private static final int INNER_RADIUS = 70;
     41     private static final int BALL_RADIUS = 100;
     42 
     43     public TouchLatencyView(Context context, AttributeSet attrs) {
     44         super(context, attrs);
     45         setOnTouchListener(this);
     46         setWillNotDraw(false);
     47         mBluePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     48         mBluePaint.setColor(0xFF0000FF);
     49         mBluePaint.setStyle(Paint.Style.FILL);
     50         mGreenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     51         mGreenPaint.setColor(0xFF00FF00);
     52         mGreenPaint.setStyle(Paint.Style.FILL);
     53         mYellowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     54         mYellowPaint.setColor(0xFFFFFF00);
     55         mYellowPaint.setStyle(Paint.Style.FILL);
     56         mRedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     57         mRedPaint.setColor(0xFFFF0000);
     58         mRedPaint.setStyle(Paint.Style.FILL);
     59 
     60         mTouching = false;
     61 
     62         mBallX = 100.0f;
     63         mBallY = 100.0f;
     64         mVelocityX = 7.0f;
     65         mVelocityY = 7.0f;
     66     }
     67 
     68     @Override
     69     public boolean onTouch(View view, MotionEvent event) {
     70         int action = event.getActionMasked();
     71         if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
     72             mTouching = true;
     73             invalidate();
     74         } else if (action == MotionEvent.ACTION_UP) {
     75             mTouching = false;
     76             invalidate();
     77             return true;
     78         } else {
     79             return true;
     80         }
     81         mTouchX = event.getX();
     82         mTouchY = event.getY();
     83         return true;
     84     }
     85 
     86     private void drawTouch(Canvas canvas) {
     87         if (!mTouching) {
     88             Log.d(LOG_TAG, "Filling background");
     89             canvas.drawColor(BACKGROUND_COLOR);
     90             return;
     91         }
     92 
     93         float deltaX = (mTouchX - mLastDrawnX);
     94         float deltaY = (mTouchY - mLastDrawnY);
     95         float scaleFactor = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 1.5f;
     96 
     97         mLastDrawnX = mTouchX;
     98         mLastDrawnY = mTouchY;
     99 
    100         canvas.drawColor(BACKGROUND_COLOR);
    101         canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 3 * scaleFactor, mRedPaint);
    102         canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 2 * scaleFactor, mYellowPaint);
    103         canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + scaleFactor, mGreenPaint);
    104         canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS, mBluePaint);
    105     }
    106 
    107     private void drawBall(Canvas canvas) {
    108         int width = canvas.getWidth();
    109         int height = canvas.getHeight();
    110 
    111         // Update position
    112         mBallX += mVelocityX;
    113         mBallY += mVelocityY;
    114 
    115         // Clamp and change velocity if necessary
    116         float left = mBallX - BALL_RADIUS;
    117         if (left < 0) {
    118             left = 0;
    119             mVelocityX *= -1;
    120         }
    121 
    122         float top = mBallY - BALL_RADIUS;
    123         if (top < 0) {
    124             top = 0;
    125             mVelocityY *= -1;
    126         }
    127 
    128         float right = mBallX + BALL_RADIUS;
    129         if (right > width) {
    130             right = width;
    131             mVelocityX *= -1;
    132         }
    133 
    134         float bottom = mBallY + BALL_RADIUS;
    135         if (bottom > height) {
    136             bottom = height;
    137             mVelocityY *= -1;
    138         }
    139 
    140         // Draw the ball
    141         canvas.drawColor(BACKGROUND_COLOR);
    142         canvas.drawOval(left, top, right, bottom, mYellowPaint);
    143         invalidate();
    144     }
    145 
    146     @Override
    147     protected void onDraw(Canvas canvas) {
    148         super.onDraw(canvas);
    149 
    150         if (mMode == 0) {
    151             drawTouch(canvas);
    152         } else {
    153             drawBall(canvas);
    154         }
    155     }
    156 
    157     public void changeMode(MenuItem item) {
    158         final int NUM_MODES = 2;
    159         final String modes[] = {"Touch", "Ball"};
    160         mMode = (mMode + 1) % NUM_MODES;
    161         invalidate();
    162         item.setTitle(modes[mMode]);
    163     }
    164 
    165     private Paint mBluePaint, mGreenPaint, mYellowPaint, mRedPaint;
    166     private int mMode;
    167 
    168     private boolean mTouching;
    169     private float mTouchX, mTouchY;
    170     private float mLastDrawnX, mLastDrawnY;
    171 
    172     private float mBallX, mBallY;
    173     private float mVelocityX, mVelocityY;
    174 }
    175 
    176 public class TouchLatencyActivity extends Activity {
    177 
    178     @Override
    179     protected void onCreate(Bundle savedInstanceState) {
    180         super.onCreate(savedInstanceState);
    181         setContentView(R.layout.activity_touch_latency);
    182 
    183         mTouchView = findViewById(R.id.canvasView);
    184     }
    185 
    186 
    187     @Override
    188     public boolean onCreateOptionsMenu(Menu menu) {
    189         // Inflate the menu; this adds items to the action bar if it is present.
    190         getMenuInflater().inflate(R.menu.menu_touch_latency, menu);
    191         return true;
    192     }
    193 
    194     @Override
    195     public boolean onOptionsItemSelected(MenuItem item) {
    196         // Handle action bar item clicks here. The action bar will
    197         // automatically handle clicks on the Home/Up button, so long
    198         // as you specify a parent activity in AndroidManifest.xml.
    199         int id = item.getItemId();
    200 
    201         //noinspection SimplifiableIfStatement
    202         if (id == R.id.action_settings) {
    203             mTouchView.changeMode(item);
    204         }
    205 
    206         return super.onOptionsItemSelected(item);
    207     }
    208 
    209     private TouchLatencyView mTouchView;
    210 }
    211