17232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski/* 27232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * Copyright (C) 2015 The Android Open Source Project 37232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * 47232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * Licensed under the Apache License, Version 2.0 (the "License"); 57232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * you may not use this file except in compliance with the License. 67232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * You may obtain a copy of the License at 77232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * 87232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * http://www.apache.org/licenses/LICENSE-2.0 97232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * 107232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * Unless required by applicable law or agreed to in writing, software 117232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * distributed under the License is distributed on an "AS IS" BASIS, 127232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * See the License for the specific language governing permissions and 147232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * limitations under the License 157232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski */ 167232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 177232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowskipackage com.android.systemui.analytics; 187232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 197232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowskiimport android.os.Build; 207232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowskiimport android.util.Log; 217232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowskiimport android.view.MotionEvent; 227232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 237232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowskiimport java.util.ArrayList; 247232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 257232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowskiimport static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session; 267232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowskiimport static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.PhoneEvent; 27c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.SensorEvent; 28c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.TouchEvent; 297232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 307232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski/** 317232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * Collects touch, sensor and phone events and converts the data to 327232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski * TouchAnalyticsProto.Session. 337232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski */ 347232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowskipublic class SensorLoggerSession { 357232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private static final String TAG = "SensorLoggerSession"; 367232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 377232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private final long mStartTimestampMillis; 387232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private final long mStartSystemTimeNanos; 397232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 407232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private long mEndTimestampMillis; 417232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private int mType; 427232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 437232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private ArrayList<TouchEvent> mMotionEvents = new ArrayList<>(); 447232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private ArrayList<SensorEvent> mSensorEvents = new ArrayList<>(); 457232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private ArrayList<PhoneEvent> mPhoneEvents = new ArrayList<>(); 467232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private int mTouchAreaHeight; 477232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private int mTouchAreaWidth; 487232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private int mResult = Session.UNKNOWN; 497232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 507232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public SensorLoggerSession(long startTimestampMillis, long startSystemTimeNanos) { 517232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mStartTimestampMillis = startTimestampMillis; 527232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mStartSystemTimeNanos = startSystemTimeNanos; 537232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mType = Session.REAL; 547232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 557232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 567232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public void end(long endTimestampMillis, int result) { 577232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mResult = result; 587232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mEndTimestampMillis = endTimestampMillis; 597232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 600e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski if (DataCollector.DEBUG) { 617232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski Log.d(TAG, "Ending session result=" + result + " it lasted for " + 627232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski (float) (mEndTimestampMillis - mStartTimestampMillis) / 1000f + "s"); 637232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 647232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 657232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 667232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public void addMotionEvent(MotionEvent motionEvent) { 677232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski TouchEvent event = motionEventToProto(motionEvent); 687232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mMotionEvents.add(event); 697232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 707232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 717232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public void addSensorEvent(android.hardware.SensorEvent eventOrig, long systemTimeNanos) { 727232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski SensorEvent event = sensorEventToProto(eventOrig, systemTimeNanos); 737232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mSensorEvents.add(event); 747232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 757232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 767232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public void addPhoneEvent(int eventType, long systemTimeNanos) { 777232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski PhoneEvent event = phoneEventToProto(eventType, systemTimeNanos); 787232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mPhoneEvents.add(event); 797232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 807232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 817232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 827232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski @Override 837232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public String toString() { 847232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski final StringBuilder sb = new StringBuilder("Session{"); 857232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append("mStartTimestampMillis=").append(mStartTimestampMillis); 867232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append(", mStartSystemTimeNanos=").append(mStartSystemTimeNanos); 877232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append(", mEndTimestampMillis=").append(mEndTimestampMillis); 887232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append(", mResult=").append(mResult); 897232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append(", mTouchAreaHeight=").append(mTouchAreaHeight); 907232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append(", mTouchAreaWidth=").append(mTouchAreaWidth); 917232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append(", mMotionEvents=[size=").append(mMotionEvents.size()).append("]"); 927232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append(", mSensorEvents=[size=").append(mSensorEvents.size()).append("]"); 937232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append(", mPhoneEvents=[size=").append(mPhoneEvents.size()).append("]"); 947232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski sb.append('}'); 957232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski return sb.toString(); 967232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 977232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 987232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public Session toProto() { 997232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski Session proto = new Session(); 1007232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setStartTimestampMillis(mStartTimestampMillis); 1017232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setDurationMillis(mEndTimestampMillis - mStartTimestampMillis); 1027232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setBuild(Build.FINGERPRINT); 1037232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setResult(mResult); 1047232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setType(mType); 1057232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents); 1067232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.touchEvents = mMotionEvents.toArray(proto.touchEvents); 1077232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.phoneEvents = mPhoneEvents.toArray(proto.phoneEvents); 1087232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setTouchAreaWidth(mTouchAreaWidth); 1097232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setTouchAreaHeight(mTouchAreaHeight); 1107232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski return proto; 1117232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 1127232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 1137232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private PhoneEvent phoneEventToProto(int eventType, long sysTimeNanos) { 1147232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski PhoneEvent proto = new PhoneEvent(); 1157232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setType(eventType); 1167232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos); 1177232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski return proto; 1187232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 1197232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 1207232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private SensorEvent sensorEventToProto(android.hardware.SensorEvent ev, long sysTimeNanos) { 1217232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski SensorEvent proto = new SensorEvent(); 1227232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setType(ev.sensor.getType()); 1237232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos); 1247232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setTimestamp(ev.timestamp); 1257232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.values = ev.values.clone(); 1267232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski return proto; 1277232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 1287232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 1297232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski private TouchEvent motionEventToProto(MotionEvent ev) { 1307232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski int count = ev.getPointerCount(); 1317232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski TouchEvent proto = new TouchEvent(); 1327232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setTimeOffsetNanos(ev.getEventTimeNano() - mStartSystemTimeNanos); 1337232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setAction(ev.getActionMasked()); 1347232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.setActionIndex(ev.getActionIndex()); 1357232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.pointers = new TouchEvent.Pointer[count]; 1367232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski for (int i = 0; i < count; i++) { 1377232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski TouchEvent.Pointer p = new TouchEvent.Pointer(); 1387232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski p.setX(ev.getX(i)); 1397232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski p.setY(ev.getY(i)); 1407232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski p.setSize(ev.getSize(i)); 1417232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski p.setPressure(ev.getPressure(i)); 1427232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski p.setId(ev.getPointerId(i)); 1437232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski proto.pointers[i] = p; 1447232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 1457232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski return proto; 1467232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 1477232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 1487232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public void setTouchArea(int width, int height) { 1497232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mTouchAreaWidth = width; 1507232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski mTouchAreaHeight = height; 1517232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 1527232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 1537232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public int getResult() { 1547232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski return mResult; 1557232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 1567232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski 1577232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski public long getStartTimestampMillis() { 1587232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski return mStartTimestampMillis; 1597232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski } 1607232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski} 161