1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2015 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License.
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.incallui.answer.impl.classifier;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.util.SparseArray;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.MotionEvent;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.ArrayList;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.concurrent.TimeUnit;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/**
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Contains data which is used to classify interaction sequences on the lockscreen. It does, for
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * example, provide information on the current touch state.
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianclass ClassifierData {
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private SparseArray<Stroke> mCurrentStrokes = new SparseArray<>();
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ArrayList<Stroke> mEndingStrokes = new ArrayList<>();
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final float mDpi;
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final float mScreenHeight;
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ClassifierData(float dpi, float screenHeight) {
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mDpi = dpi;
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mScreenHeight = screenHeight / dpi;
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void update(MotionEvent event) {
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mEndingStrokes.clear();
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int action = event.getActionMasked();
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (action == MotionEvent.ACTION_DOWN) {
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mCurrentStrokes.clear();
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    for (int i = 0; i < event.getPointerCount(); i++) {
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int id = event.getPointerId(i);
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (mCurrentStrokes.get(id) == null) {
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // TODO (keyboardr): See if there's a way to use event.getEventTimeNanos() instead
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mCurrentStrokes.put(
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            id, new Stroke(TimeUnit.MILLISECONDS.toNanos(event.getEventTime()), mDpi));
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mCurrentStrokes
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .get(id)
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .addPoint(
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              event.getX(i), event.getY(i), TimeUnit.MILLISECONDS.toNanos(event.getEventTime()));
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (action == MotionEvent.ACTION_UP
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          || action == MotionEvent.ACTION_CANCEL
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          || (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) {
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mEndingStrokes.add(getStroke(id));
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  void cleanUp(MotionEvent event) {
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mEndingStrokes.clear();
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int action = event.getActionMasked();
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    for (int i = 0; i < event.getPointerCount(); i++) {
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int id = event.getPointerId(i);
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (action == MotionEvent.ACTION_UP
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          || action == MotionEvent.ACTION_CANCEL
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          || (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) {
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mCurrentStrokes.remove(id);
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** @return the list of Strokes which are ending in the recently added MotionEvent */
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ArrayList<Stroke> getEndingStrokes() {
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mEndingStrokes;
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param id the id from MotionEvent
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return the Stroke assigned to the id
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public Stroke getStroke(int id) {
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mCurrentStrokes.get(id);
90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** @return the height of the screen in inches */
93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public float getScreenHeight() {
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mScreenHeight;
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
97