• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 org.chromium.latency.walt;
18 
19 import android.util.Log;
20 import android.view.MotionEvent;
21 
22 import java.lang.reflect.Method;
23 
24 /**
25  * A convenient representation of MotionEvent events
26  * - microsecond accuracy
27  * - no bundling of ACTION_MOVE events
28  */
29 
30 public class UsMotionEvent {
31 
32     public long physicalTime, kernelTime, createTime;
33     public float x, y;
34     public int slot;
35     public int action;
36     public int num;
37     public String metadata;
38     public long baseTime;
39 
40     public boolean isOk = false;
41 
42     /**
43      *
44      * @param event - MotionEvent as received by the handler.
45      * @param baseTime - base time of the last clock sync.
46      */
UsMotionEvent(MotionEvent event, long baseTime)47     public UsMotionEvent(MotionEvent event, long baseTime) {
48         createTime = RemoteClockInfo.microTime() - baseTime;
49         this.baseTime = baseTime;
50         slot = -1;
51         kernelTime = getEventTimeMicro(event) - baseTime;
52         x = event.getX();
53         y = event.getY();
54         action = event.getAction();
55     }
56 
UsMotionEvent(MotionEvent event, long baseTime, int pos)57     public UsMotionEvent(MotionEvent event, long baseTime, int pos) {
58         createTime = RemoteClockInfo.microTime() - baseTime;
59         this.baseTime = baseTime;
60         slot = pos;
61         action = MotionEvent.ACTION_MOVE; // Only MOVE events get bundled with history
62 
63         kernelTime = getHistoricalEventTimeMicro(event, pos) - baseTime;
64         x = event.getHistoricalX(pos);
65         y = event.getHistoricalY(pos);
66     }
67 
getActionString()68     public String getActionString() {
69         return actionToString(action);
70     }
71 
72 
toString()73     public String toString() {
74         return String.format("%d %f %f",
75                 kernelTime, x, y);
76 
77     }
78 
toStringLong()79     public String toStringLong() {
80         return String.format("Event: t=%d x=%.1f y=%.1f slot=%d num=%d %s",
81                 kernelTime, x, y, slot, num, actionToString(action));
82 
83     }
84 
85     // The MotionEvent.actionToString is not present before API 19
actionToString(int action)86     public static String actionToString(int action) {
87         switch (action) {
88             case MotionEvent.ACTION_DOWN:
89                 return "ACTION_DOWN";
90             case MotionEvent.ACTION_UP:
91                 return "ACTION_UP";
92             case MotionEvent.ACTION_CANCEL:
93                 return "ACTION_CANCEL";
94             case MotionEvent.ACTION_OUTSIDE:
95                 return "ACTION_OUTSIDE";
96             case MotionEvent.ACTION_MOVE:
97                 return "ACTION_MOVE";
98             case MotionEvent.ACTION_HOVER_MOVE:
99                 return "ACTION_HOVER_MOVE";
100             case MotionEvent.ACTION_SCROLL:
101                 return "ACTION_SCROLL";
102             case MotionEvent.ACTION_HOVER_ENTER:
103                 return "ACTION_HOVER_ENTER";
104             case MotionEvent.ACTION_HOVER_EXIT:
105                 return "ACTION_HOVER_EXIT";
106         }
107         return "UNKNOWN_ACTION";
108     }
109 
110     /**
111      MotionEvent.getEventTime() function only provides millisecond resolution.
112      There is a MotionEvent.getEventTimeNano() function but for some reason it
113      is hidden by @hide which means it can't be called directly.
114      Calling is via reflection.
115 
116      See:
117      http://stackoverflow.com/questions/17035271/what-does-hide-mean-in-the-android-source-code
118      */
getEventTimeMicro(MotionEvent event)119     private long getEventTimeMicro(MotionEvent event) {
120         long t_nanos = -1;
121         try {
122             Class cls = Class.forName("android.view.MotionEvent");
123             Method myTimeGetter = cls.getMethod("getEventTimeNano");
124             t_nanos = (long) myTimeGetter.invoke(event);
125         } catch (Exception e) {
126             Log.i("WALT.MsMotionEvent", e.getMessage());
127         }
128 
129         return t_nanos / 1000;
130     }
131 
getHistoricalEventTimeMicro(MotionEvent event, int pos)132     private long getHistoricalEventTimeMicro(MotionEvent event, int pos) {
133         long t_nanos = -1;
134         try {
135             Class cls = Class.forName("android.view.MotionEvent");
136             Method myTimeGetter = cls.getMethod("getHistoricalEventTimeNano", new Class[] {int.class});
137             t_nanos = (long) myTimeGetter.invoke(event, new Object[]{pos});
138         } catch (Exception e) {
139             Log.i("WALT.MsMotionEvent", e.getMessage());
140         }
141 
142         return t_nanos / 1000;
143     }
144 
145 }
146 
147