1 /* 2 * Copyright (C) 2015 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.android.incallui.answer.impl.classifier; 18 19 import android.util.SparseArray; 20 import android.view.MotionEvent; 21 import java.util.ArrayList; 22 import java.util.concurrent.TimeUnit; 23 24 /** 25 * Contains data which is used to classify interaction sequences on the lockscreen. It does, for 26 * example, provide information on the current touch state. 27 */ 28 class ClassifierData { 29 private SparseArray<Stroke> mCurrentStrokes = new SparseArray<>(); 30 private ArrayList<Stroke> mEndingStrokes = new ArrayList<>(); 31 private final float mDpi; 32 private final float mScreenHeight; 33 34 public ClassifierData(float dpi, float screenHeight) { 35 mDpi = dpi; 36 mScreenHeight = screenHeight / dpi; 37 } 38 39 public void update(MotionEvent event) { 40 mEndingStrokes.clear(); 41 int action = event.getActionMasked(); 42 if (action == MotionEvent.ACTION_DOWN) { 43 mCurrentStrokes.clear(); 44 } 45 46 for (int i = 0; i < event.getPointerCount(); i++) { 47 int id = event.getPointerId(i); 48 if (mCurrentStrokes.get(id) == null) { 49 // TODO (keyboardr): See if there's a way to use event.getEventTimeNanos() instead 50 mCurrentStrokes.put( 51 id, new Stroke(TimeUnit.MILLISECONDS.toNanos(event.getEventTime()), mDpi)); 52 } 53 mCurrentStrokes 54 .get(id) 55 .addPoint( 56 event.getX(i), event.getY(i), TimeUnit.MILLISECONDS.toNanos(event.getEventTime())); 57 58 if (action == MotionEvent.ACTION_UP 59 || action == MotionEvent.ACTION_CANCEL 60 || (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) { 61 mEndingStrokes.add(getStroke(id)); 62 } 63 } 64 } 65 66 void cleanUp(MotionEvent event) { 67 mEndingStrokes.clear(); 68 int action = event.getActionMasked(); 69 for (int i = 0; i < event.getPointerCount(); i++) { 70 int id = event.getPointerId(i); 71 if (action == MotionEvent.ACTION_UP 72 || action == MotionEvent.ACTION_CANCEL 73 || (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) { 74 mCurrentStrokes.remove(id); 75 } 76 } 77 } 78 79 /** @return the list of Strokes which are ending in the recently added MotionEvent */ 80 public ArrayList<Stroke> getEndingStrokes() { 81 return mEndingStrokes; 82 } 83 84 /** 85 * @param id the id from MotionEvent 86 * @return the Stroke assigned to the id 87 */ 88 public Stroke getStroke(int id) { 89 return mCurrentStrokes.get(id); 90 } 91 92 /** @return the height of the screen in inches */ 93 public float getScreenHeight() { 94 return mScreenHeight; 95 } 96 } 97