/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.systemui.analytics; import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session; import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.PhoneEvent; import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.SensorEvent; import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.TouchEvent; import android.os.Build; import android.util.Log; import android.view.MotionEvent; import java.util.ArrayList; /** * Collects touch, sensor and phone events and converts the data to * TouchAnalyticsProto.Session. */ public class SensorLoggerSession { private static final String TAG = "SensorLoggerSession"; private final long mStartTimestampMillis; private final long mStartSystemTimeNanos; private long mEndTimestampMillis; private int mType; private ArrayList mMotionEvents = new ArrayList<>(); private ArrayList mSensorEvents = new ArrayList<>(); private ArrayList mPhoneEvents = new ArrayList<>(); private int mTouchAreaHeight; private int mTouchAreaWidth; private int mResult = Session.UNKNOWN; public SensorLoggerSession(long startTimestampMillis, long startSystemTimeNanos) { mStartTimestampMillis = startTimestampMillis; mStartSystemTimeNanos = startSystemTimeNanos; mType = Session.REAL; } public void setType(int type) { mType = type; } public void end(long endTimestampMillis, int result) { mResult = result; mEndTimestampMillis = endTimestampMillis; if (DataCollector.DEBUG) { Log.d(TAG, "Ending session result=" + result + " it lasted for " + (float) (mEndTimestampMillis - mStartTimestampMillis) / 1000f + "s"); } } public void addMotionEvent(MotionEvent motionEvent) { TouchEvent event = motionEventToProto(motionEvent); mMotionEvents.add(event); } public void addSensorEvent(android.hardware.SensorEvent eventOrig, long systemTimeNanos) { SensorEvent event = sensorEventToProto(eventOrig, systemTimeNanos); mSensorEvents.add(event); } public void addPhoneEvent(int eventType, long systemTimeNanos) { PhoneEvent event = phoneEventToProto(eventType, systemTimeNanos); mPhoneEvents.add(event); } @Override public String toString() { final StringBuilder sb = new StringBuilder("Session{"); sb.append("mStartTimestampMillis=").append(mStartTimestampMillis); sb.append(", mStartSystemTimeNanos=").append(mStartSystemTimeNanos); sb.append(", mEndTimestampMillis=").append(mEndTimestampMillis); sb.append(", mResult=").append(mResult); sb.append(", mTouchAreaHeight=").append(mTouchAreaHeight); sb.append(", mTouchAreaWidth=").append(mTouchAreaWidth); sb.append(", mMotionEvents=[size=").append(mMotionEvents.size()).append("]"); sb.append(", mSensorEvents=[size=").append(mSensorEvents.size()).append("]"); sb.append(", mPhoneEvents=[size=").append(mPhoneEvents.size()).append("]"); sb.append('}'); return sb.toString(); } public Session toProto() { Session proto = new Session(); proto.startTimestampMillis = mStartTimestampMillis; proto.durationMillis = mEndTimestampMillis - mStartTimestampMillis; proto.build = Build.FINGERPRINT; proto.deviceId = Build.DEVICE; proto.result = mResult; proto.type = mType; proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents); proto.touchEvents = mMotionEvents.toArray(proto.touchEvents); proto.phoneEvents = mPhoneEvents.toArray(proto.phoneEvents); proto.touchAreaWidth = mTouchAreaWidth; proto.touchAreaHeight = mTouchAreaHeight; return proto; } private PhoneEvent phoneEventToProto(int eventType, long sysTimeNanos) { PhoneEvent proto = new PhoneEvent(); proto.type = eventType; proto.timeOffsetNanos = sysTimeNanos - mStartSystemTimeNanos; return proto; } private SensorEvent sensorEventToProto(android.hardware.SensorEvent ev, long sysTimeNanos) { SensorEvent proto = new SensorEvent(); proto.type = ev.sensor.getType(); proto.timeOffsetNanos = sysTimeNanos - mStartSystemTimeNanos; proto.timestamp = ev.timestamp; proto.values = ev.values.clone(); return proto; } private TouchEvent motionEventToProto(MotionEvent ev) { int count = ev.getPointerCount(); TouchEvent proto = new TouchEvent(); proto.timeOffsetNanos = ev.getEventTimeNano() - mStartSystemTimeNanos; proto.action = ev.getActionMasked(); proto.actionIndex = ev.getActionIndex(); proto.pointers = new TouchEvent.Pointer[count]; for (int i = 0; i < count; i++) { TouchEvent.Pointer p = new TouchEvent.Pointer(); p.x = ev.getX(i); p.y = ev.getY(i); p.size = ev.getSize(i); p.pressure = ev.getPressure(i); p.id = ev.getPointerId(i); proto.pointers[i] = p; } return proto; } public void setTouchArea(int width, int height) { mTouchAreaWidth = width; mTouchAreaHeight = height; } public int getResult() { return mResult; } public long getStartTimestampMillis() { return mStartTimestampMillis; } }