| /* |
| * 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 android.os.Build; |
| import android.util.Log; |
| import android.view.MotionEvent; |
| |
| import java.util.ArrayList; |
| |
| import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session; |
| import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.PhoneEvent; |
| import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.SensorEvent; |
| import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.TouchEvent; |
| |
| /** |
| * 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<TouchEvent> mMotionEvents = new ArrayList<>(); |
| private ArrayList<SensorEvent> mSensorEvents = new ArrayList<>(); |
| private ArrayList<PhoneEvent> 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.setStartTimestampMillis(mStartTimestampMillis); |
| proto.setDurationMillis(mEndTimestampMillis - mStartTimestampMillis); |
| proto.setBuild(Build.FINGERPRINT); |
| proto.setResult(mResult); |
| proto.setType(mType); |
| proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents); |
| proto.touchEvents = mMotionEvents.toArray(proto.touchEvents); |
| proto.phoneEvents = mPhoneEvents.toArray(proto.phoneEvents); |
| proto.setTouchAreaWidth(mTouchAreaWidth); |
| proto.setTouchAreaHeight(mTouchAreaHeight); |
| return proto; |
| } |
| |
| private PhoneEvent phoneEventToProto(int eventType, long sysTimeNanos) { |
| PhoneEvent proto = new PhoneEvent(); |
| proto.setType(eventType); |
| proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos); |
| return proto; |
| } |
| |
| private SensorEvent sensorEventToProto(android.hardware.SensorEvent ev, long sysTimeNanos) { |
| SensorEvent proto = new SensorEvent(); |
| proto.setType(ev.sensor.getType()); |
| proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos); |
| proto.setTimestamp(ev.timestamp); |
| proto.values = ev.values.clone(); |
| return proto; |
| } |
| |
| private TouchEvent motionEventToProto(MotionEvent ev) { |
| int count = ev.getPointerCount(); |
| TouchEvent proto = new TouchEvent(); |
| proto.setTimeOffsetNanos(ev.getEventTimeNano() - mStartSystemTimeNanos); |
| proto.setAction(ev.getActionMasked()); |
| proto.setActionIndex(ev.getActionIndex()); |
| proto.pointers = new TouchEvent.Pointer[count]; |
| for (int i = 0; i < count; i++) { |
| TouchEvent.Pointer p = new TouchEvent.Pointer(); |
| p.setX(ev.getX(i)); |
| p.setY(ev.getY(i)); |
| p.setSize(ev.getSize(i)); |
| p.setPressure(ev.getPressure(i)); |
| p.setId(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; |
| } |
| } |