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
567bb38a941b056e8e7cb41151d927313ec6c138d5Adrian Roos    public void setType(int type) {
577bb38a941b056e8e7cb41151d927313ec6c138d5Adrian Roos        mType = type;
587bb38a941b056e8e7cb41151d927313ec6c138d5Adrian Roos    }
597bb38a941b056e8e7cb41151d927313ec6c138d5Adrian Roos
607232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public void end(long endTimestampMillis, int result) {
617232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        mResult = result;
627232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        mEndTimestampMillis = endTimestampMillis;
637232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
640e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        if (DataCollector.DEBUG) {
657232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski            Log.d(TAG, "Ending session result=" + result + " it lasted for " +
667232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski                    (float) (mEndTimestampMillis - mStartTimestampMillis) / 1000f + "s");
677232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        }
687232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
697232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
707232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public void addMotionEvent(MotionEvent motionEvent) {
717232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        TouchEvent event = motionEventToProto(motionEvent);
727232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        mMotionEvents.add(event);
737232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
747232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
757232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public void addSensorEvent(android.hardware.SensorEvent eventOrig, long systemTimeNanos) {
767232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        SensorEvent event = sensorEventToProto(eventOrig, systemTimeNanos);
777232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        mSensorEvents.add(event);
787232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
797232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
807232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public void addPhoneEvent(int eventType, long systemTimeNanos) {
817232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        PhoneEvent event = phoneEventToProto(eventType, systemTimeNanos);
827232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        mPhoneEvents.add(event);
837232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
847232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
857232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
867232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    @Override
877232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public String toString() {
887232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        final StringBuilder sb = new StringBuilder("Session{");
897232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append("mStartTimestampMillis=").append(mStartTimestampMillis);
907232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append(", mStartSystemTimeNanos=").append(mStartSystemTimeNanos);
917232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append(", mEndTimestampMillis=").append(mEndTimestampMillis);
927232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append(", mResult=").append(mResult);
937232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append(", mTouchAreaHeight=").append(mTouchAreaHeight);
947232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append(", mTouchAreaWidth=").append(mTouchAreaWidth);
957232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append(", mMotionEvents=[size=").append(mMotionEvents.size()).append("]");
967232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append(", mSensorEvents=[size=").append(mSensorEvents.size()).append("]");
977232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append(", mPhoneEvents=[size=").append(mPhoneEvents.size()).append("]");
987232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        sb.append('}');
997232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        return sb.toString();
1007232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
1017232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
1027232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public Session toProto() {
1037232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        Session proto = new Session();
1047232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setStartTimestampMillis(mStartTimestampMillis);
1057232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setDurationMillis(mEndTimestampMillis - mStartTimestampMillis);
1067232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setBuild(Build.FINGERPRINT);
1077232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setResult(mResult);
1087232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setType(mType);
1097232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents);
1107232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.touchEvents = mMotionEvents.toArray(proto.touchEvents);
1117232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.phoneEvents = mPhoneEvents.toArray(proto.phoneEvents);
1127232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setTouchAreaWidth(mTouchAreaWidth);
1137232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setTouchAreaHeight(mTouchAreaHeight);
1147232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        return proto;
1157232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
1167232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
1177232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    private PhoneEvent phoneEventToProto(int eventType, long sysTimeNanos) {
1187232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        PhoneEvent proto = new PhoneEvent();
1197232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setType(eventType);
1207232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos);
1217232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        return proto;
1227232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
1237232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
1247232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    private SensorEvent sensorEventToProto(android.hardware.SensorEvent ev, long sysTimeNanos) {
1257232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        SensorEvent proto = new SensorEvent();
1267232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setType(ev.sensor.getType());
1277232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos);
1287232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setTimestamp(ev.timestamp);
1297232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.values = ev.values.clone();
1307232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        return proto;
1317232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
1327232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
1337232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    private TouchEvent motionEventToProto(MotionEvent ev) {
1347232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        int count = ev.getPointerCount();
1357232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        TouchEvent proto = new TouchEvent();
1367232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setTimeOffsetNanos(ev.getEventTimeNano() - mStartSystemTimeNanos);
1377232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setAction(ev.getActionMasked());
1387232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.setActionIndex(ev.getActionIndex());
1397232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        proto.pointers = new TouchEvent.Pointer[count];
1407232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        for (int i = 0; i < count; i++) {
1417232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski            TouchEvent.Pointer p = new TouchEvent.Pointer();
1427232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski            p.setX(ev.getX(i));
1437232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski            p.setY(ev.getY(i));
1447232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski            p.setSize(ev.getSize(i));
1457232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski            p.setPressure(ev.getPressure(i));
1467232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski            p.setId(ev.getPointerId(i));
1477232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski            proto.pointers[i] = p;
1487232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        }
1497232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        return proto;
1507232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
1517232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
1527232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public void setTouchArea(int width, int height) {
1537232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        mTouchAreaWidth = width;
1547232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        mTouchAreaHeight = height;
1557232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
1567232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
1577232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public int getResult() {
1587232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        return mResult;
1597232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
1607232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski
1617232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    public long getStartTimestampMillis() {
1627232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski        return mStartTimestampMillis;
1637232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski    }
1647232332dc963c2ce55dda1a3a0367080d5494503Blazej Magnowski}
165