Home | History | Annotate | Download | only in analytics
      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.systemui.analytics;
     18 
     19 import android.os.Build;
     20 import android.util.Log;
     21 import android.view.MotionEvent;
     22 
     23 import java.util.ArrayList;
     24 
     25 import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session;
     26 import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.PhoneEvent;
     27 import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.SensorEvent;
     28 import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.TouchEvent;
     29 
     30 /**
     31  * Collects touch, sensor and phone events and converts the data to
     32  * TouchAnalyticsProto.Session.
     33  */
     34 public class SensorLoggerSession {
     35     private static final String TAG = "SensorLoggerSession";
     36 
     37     private final long mStartTimestampMillis;
     38     private final long mStartSystemTimeNanos;
     39 
     40     private long mEndTimestampMillis;
     41     private int mType;
     42 
     43     private ArrayList<TouchEvent> mMotionEvents = new ArrayList<>();
     44     private ArrayList<SensorEvent> mSensorEvents = new ArrayList<>();
     45     private ArrayList<PhoneEvent> mPhoneEvents = new ArrayList<>();
     46     private int mTouchAreaHeight;
     47     private int mTouchAreaWidth;
     48     private int mResult = Session.UNKNOWN;
     49 
     50     public SensorLoggerSession(long startTimestampMillis, long startSystemTimeNanos) {
     51         mStartTimestampMillis = startTimestampMillis;
     52         mStartSystemTimeNanos = startSystemTimeNanos;
     53         mType = Session.REAL;
     54     }
     55 
     56     public void setType(int type) {
     57         mType = type;
     58     }
     59 
     60     public void end(long endTimestampMillis, int result) {
     61         mResult = result;
     62         mEndTimestampMillis = endTimestampMillis;
     63 
     64         if (DataCollector.DEBUG) {
     65             Log.d(TAG, "Ending session result=" + result + " it lasted for " +
     66                     (float) (mEndTimestampMillis - mStartTimestampMillis) / 1000f + "s");
     67         }
     68     }
     69 
     70     public void addMotionEvent(MotionEvent motionEvent) {
     71         TouchEvent event = motionEventToProto(motionEvent);
     72         mMotionEvents.add(event);
     73     }
     74 
     75     public void addSensorEvent(android.hardware.SensorEvent eventOrig, long systemTimeNanos) {
     76         SensorEvent event = sensorEventToProto(eventOrig, systemTimeNanos);
     77         mSensorEvents.add(event);
     78     }
     79 
     80     public void addPhoneEvent(int eventType, long systemTimeNanos) {
     81         PhoneEvent event = phoneEventToProto(eventType, systemTimeNanos);
     82         mPhoneEvents.add(event);
     83     }
     84 
     85 
     86     @Override
     87     public String toString() {
     88         final StringBuilder sb = new StringBuilder("Session{");
     89         sb.append("mStartTimestampMillis=").append(mStartTimestampMillis);
     90         sb.append(", mStartSystemTimeNanos=").append(mStartSystemTimeNanos);
     91         sb.append(", mEndTimestampMillis=").append(mEndTimestampMillis);
     92         sb.append(", mResult=").append(mResult);
     93         sb.append(", mTouchAreaHeight=").append(mTouchAreaHeight);
     94         sb.append(", mTouchAreaWidth=").append(mTouchAreaWidth);
     95         sb.append(", mMotionEvents=[size=").append(mMotionEvents.size()).append("]");
     96         sb.append(", mSensorEvents=[size=").append(mSensorEvents.size()).append("]");
     97         sb.append(", mPhoneEvents=[size=").append(mPhoneEvents.size()).append("]");
     98         sb.append('}');
     99         return sb.toString();
    100     }
    101 
    102     public Session toProto() {
    103         Session proto = new Session();
    104         proto.setStartTimestampMillis(mStartTimestampMillis);
    105         proto.setDurationMillis(mEndTimestampMillis - mStartTimestampMillis);
    106         proto.setBuild(Build.FINGERPRINT);
    107         proto.setResult(mResult);
    108         proto.setType(mType);
    109         proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents);
    110         proto.touchEvents = mMotionEvents.toArray(proto.touchEvents);
    111         proto.phoneEvents = mPhoneEvents.toArray(proto.phoneEvents);
    112         proto.setTouchAreaWidth(mTouchAreaWidth);
    113         proto.setTouchAreaHeight(mTouchAreaHeight);
    114         return proto;
    115     }
    116 
    117     private PhoneEvent phoneEventToProto(int eventType, long sysTimeNanos) {
    118         PhoneEvent proto = new PhoneEvent();
    119         proto.setType(eventType);
    120         proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos);
    121         return proto;
    122     }
    123 
    124     private SensorEvent sensorEventToProto(android.hardware.SensorEvent ev, long sysTimeNanos) {
    125         SensorEvent proto = new SensorEvent();
    126         proto.setType(ev.sensor.getType());
    127         proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos);
    128         proto.setTimestamp(ev.timestamp);
    129         proto.values = ev.values.clone();
    130         return proto;
    131     }
    132 
    133     private TouchEvent motionEventToProto(MotionEvent ev) {
    134         int count = ev.getPointerCount();
    135         TouchEvent proto = new TouchEvent();
    136         proto.setTimeOffsetNanos(ev.getEventTimeNano() - mStartSystemTimeNanos);
    137         proto.setAction(ev.getActionMasked());
    138         proto.setActionIndex(ev.getActionIndex());
    139         proto.pointers = new TouchEvent.Pointer[count];
    140         for (int i = 0; i < count; i++) {
    141             TouchEvent.Pointer p = new TouchEvent.Pointer();
    142             p.setX(ev.getX(i));
    143             p.setY(ev.getY(i));
    144             p.setSize(ev.getSize(i));
    145             p.setPressure(ev.getPressure(i));
    146             p.setId(ev.getPointerId(i));
    147             proto.pointers[i] = p;
    148         }
    149         return proto;
    150     }
    151 
    152     public void setTouchArea(int width, int height) {
    153         mTouchAreaWidth = width;
    154         mTouchAreaHeight = height;
    155     }
    156 
    157     public int getResult() {
    158         return mResult;
    159     }
    160 
    161     public long getStartTimestampMillis() {
    162         return mStartTimestampMillis;
    163     }
    164 }
    165