Home | History | Annotate | Download | only in classifier
      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