Merge "System to track touch and sensor events before unlocking the phone"
This commit is contained in:
committed by
Android (Google) Code Review
commit
c3866bf81f
@@ -3,13 +3,15 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-proto-files-under,src) \
|
||||
src/com/android/systemui/EventLogTags.logtags
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := Keyguard
|
||||
LOCAL_JAVA_LIBRARIES := telephony-common
|
||||
|
||||
LOCAL_PACKAGE_NAME := SystemUI
|
||||
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
|
||||
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
|
||||
LOCAL_CERTIFICATE := platform
|
||||
LOCAL_PRIVILEGED_MODULE := true
|
||||
|
||||
|
||||
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* 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.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session;
|
||||
import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.PhoneEvent;
|
||||
|
||||
/**
|
||||
* Tracks touch, sensor and phone events when the lockscreen is on. If the phone is unlocked
|
||||
* the data containing these events is saved to a file. This data is collected
|
||||
* to analyze how a human interaction looks like.
|
||||
*
|
||||
* A session starts when the screen is turned on.
|
||||
* A session ends when the screen is turned off or user unlocks the phone.
|
||||
*/
|
||||
public class LockedPhoneAnalytics implements SensorEventListener {
|
||||
private static final String TAG = "LockedPhoneAnalytics";
|
||||
private static final String ANALYTICS_ENABLE = "locked_phone_analytics_enable";
|
||||
private static final String ENFORCE_BOUNCER = "locked_phone_analytics_enforce_bouncer";
|
||||
private static final String COLLECT_BAD_TOCUHES = "locked_phone_analytics_collect_bad_touches";
|
||||
|
||||
private static final long TIMEOUT_MILLIS = 11000; // 11 seconds.
|
||||
public static final boolean DEBUG = false;
|
||||
|
||||
private static final int[] SENSORS = new int[] {
|
||||
Sensor.TYPE_ACCELEROMETER,
|
||||
Sensor.TYPE_GYROSCOPE,
|
||||
Sensor.TYPE_PROXIMITY,
|
||||
Sensor.TYPE_LIGHT,
|
||||
Sensor.TYPE_ROTATION_VECTOR,
|
||||
};
|
||||
|
||||
private final Handler mHandler = new Handler();
|
||||
protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateConfiguration();
|
||||
}
|
||||
};
|
||||
|
||||
private final SensorManager mSensorManager;
|
||||
private final Context mContext;
|
||||
|
||||
// Err on the side of caution, so logging is not started after a crash even tough the screen
|
||||
// is off.
|
||||
private SensorLoggerSession mCurrentSession = null;
|
||||
|
||||
private boolean mEnableAnalytics = false;
|
||||
private boolean mEnforceBouncer = false;
|
||||
private boolean mTimeoutActive = false;
|
||||
private boolean mCollectBadTouches = false;
|
||||
private boolean mBouncerOn = false;
|
||||
private boolean mCornerSwiping = false;
|
||||
private boolean mTrackingStarted = false;
|
||||
|
||||
private int mState = StatusBarState.SHADE;
|
||||
|
||||
private static LockedPhoneAnalytics sInstance = null;
|
||||
|
||||
private LockedPhoneAnalytics(Context context) {
|
||||
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
||||
mContext = context;
|
||||
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Secure.getUriFor(ANALYTICS_ENABLE), false,
|
||||
mSettingsObserver,
|
||||
UserHandle.USER_ALL);
|
||||
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Secure.getUriFor(ENFORCE_BOUNCER), false,
|
||||
mSettingsObserver,
|
||||
UserHandle.USER_ALL);
|
||||
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Secure.getUriFor(COLLECT_BAD_TOCUHES), false,
|
||||
mSettingsObserver,
|
||||
UserHandle.USER_ALL);
|
||||
|
||||
updateConfiguration();
|
||||
}
|
||||
|
||||
public static LockedPhoneAnalytics getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new LockedPhoneAnalytics(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private void updateConfiguration() {
|
||||
mEnableAnalytics = Build.IS_DEBUGGABLE && 0 != Settings.Secure.getInt(
|
||||
mContext.getContentResolver(),
|
||||
ANALYTICS_ENABLE, 0);
|
||||
mEnforceBouncer = mEnableAnalytics && 0 != Settings.Secure.getInt(
|
||||
mContext.getContentResolver(),
|
||||
ENFORCE_BOUNCER, 0);
|
||||
mCollectBadTouches = mEnableAnalytics && 0 != Settings.Secure.getInt(
|
||||
mContext.getContentResolver(),
|
||||
COLLECT_BAD_TOCUHES, 0);
|
||||
}
|
||||
|
||||
private boolean sessionEntrypoint() {
|
||||
if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
|
||||
&& mEnableAnalytics && mCurrentSession == null) {
|
||||
onSessionStart();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void sessionExitpoint(int result) {
|
||||
if (mEnableAnalytics && mCurrentSession != null) {
|
||||
onSessionEnd(result);
|
||||
}
|
||||
}
|
||||
|
||||
private void onSessionStart() {
|
||||
mBouncerOn = false;
|
||||
mCornerSwiping = false;
|
||||
mTrackingStarted = false;
|
||||
mCurrentSession = new SensorLoggerSession(System.currentTimeMillis(), System.nanoTime());
|
||||
for (int sensorType : SENSORS) {
|
||||
Sensor s = mSensorManager.getDefaultSensor(sensorType);
|
||||
if (s != null) {
|
||||
mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onSessionEnd(int result) {
|
||||
SensorLoggerSession session = mCurrentSession;
|
||||
mCurrentSession = null;
|
||||
|
||||
session.end(System.currentTimeMillis(), result);
|
||||
queueSession(session);
|
||||
}
|
||||
|
||||
private void queueSession(final SensorLoggerSession currentSession) {
|
||||
AsyncTask.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
byte[] b = Session.toByteArray(currentSession.toProto());
|
||||
String dir = mContext.getFilesDir().getAbsolutePath();
|
||||
if (currentSession.getResult() != Session.SUCCESS) {
|
||||
if (!mCollectBadTouches) {
|
||||
return;
|
||||
}
|
||||
dir += "/bad_touches";
|
||||
} else {
|
||||
dir += "/good_touches";
|
||||
}
|
||||
|
||||
File file = new File(dir);
|
||||
file.mkdir();
|
||||
File touch = new File(file, "trace_" + System.currentTimeMillis());
|
||||
|
||||
try {
|
||||
new FileOutputStream(touch).write(b);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void onSensorChanged(SensorEvent event) {
|
||||
if (mEnableAnalytics && mCurrentSession != null) {
|
||||
mCurrentSession.addSensorEvent(event, System.nanoTime());
|
||||
enforceTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
private void enforceTimeout() {
|
||||
if (mTimeoutActive) {
|
||||
if (System.currentTimeMillis() - mCurrentSession.getStartTimestampMillis()
|
||||
> TIMEOUT_MILLIS) {
|
||||
onSessionEnd(Session.UNKNOWN);
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Analytics timed out.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
}
|
||||
|
||||
public boolean shouldEnforceBouncer() {
|
||||
return mEnforceBouncer;
|
||||
}
|
||||
|
||||
public void setStatusBarState(int state) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
public void onScreenOn() {
|
||||
if (sessionEntrypoint()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onScreenOn");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_SCREEN_ON);
|
||||
}
|
||||
}
|
||||
|
||||
public void onScreenOnFromTouch() {
|
||||
if (sessionEntrypoint()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onScreenOnFromTouch");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_SCREEN_ON_FROM_TOUCH);
|
||||
}
|
||||
}
|
||||
|
||||
public void onScreenOff() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onScreenOff");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_SCREEN_OFF);
|
||||
sessionExitpoint(Session.FAILURE);
|
||||
}
|
||||
|
||||
public void onSucccessfulUnlock() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onSuccessfulUnlock");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_SUCCESSFUL_UNLOCK);
|
||||
sessionExitpoint(Session.SUCCESS);
|
||||
}
|
||||
|
||||
public void onBouncerShown() {
|
||||
if (!mBouncerOn) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBouncerShown");
|
||||
}
|
||||
mBouncerOn = true;
|
||||
addEvent(PhoneEvent.ON_BOUNCER_SHOWN);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBouncerHidden() {
|
||||
if (mBouncerOn) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBouncerHidden");
|
||||
}
|
||||
mBouncerOn = false;
|
||||
addEvent(PhoneEvent.ON_BOUNCER_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
public void onQsDown() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onQsDown");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_QS_DOWN);
|
||||
}
|
||||
|
||||
public void setQsExpanded(boolean expanded) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setQsExpanded = " + expanded);
|
||||
}
|
||||
if (expanded) {
|
||||
addEvent(PhoneEvent.SET_QS_EXPANDED_TRUE);
|
||||
} else {
|
||||
addEvent(PhoneEvent.SET_QS_EXPANDED_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
public void onTrackingStarted() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onTrackingStarted");
|
||||
}
|
||||
mTrackingStarted = true;
|
||||
addEvent(PhoneEvent.ON_TRACKING_STARTED);
|
||||
}
|
||||
|
||||
public void onTrackingStopped() {
|
||||
if (mTrackingStarted) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onTrackingStopped");
|
||||
}
|
||||
mTrackingStarted = false;
|
||||
addEvent(PhoneEvent.ON_TRACKING_STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
public void onNotificationActive() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onNotificationActive");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_NOTIFICATION_ACTIVE);
|
||||
}
|
||||
|
||||
|
||||
public void onNotificationDoubleTap() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onNotificationDoubleTap");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_NOTIFICATION_DOUBLE_TAP);
|
||||
}
|
||||
|
||||
public void setNotificationExpanded() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setNotificationExpanded");
|
||||
}
|
||||
addEvent(PhoneEvent.SET_NOTIFICATION_EXPANDED);
|
||||
}
|
||||
|
||||
public void onNotificatonStartDraggingDown() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onNotificationStartDraggingDown");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_NOTIFICATION_START_DRAGGING_DOWN);
|
||||
}
|
||||
|
||||
public void onNotificatonStopDraggingDown() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onNotificationStopDraggingDown");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_NOTIFICATION_STOP_DRAGGING_DOWN);
|
||||
}
|
||||
|
||||
public void onNotificationDismissed() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onNotificationDismissed");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_NOTIFICATION_DISMISSED);
|
||||
}
|
||||
|
||||
public void onNotificatonStartDismissing() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onNotificationStartDismissing");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_NOTIFICATION_START_DISMISSING);
|
||||
}
|
||||
|
||||
public void onNotificatonStopDismissing() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onNotificationStopDismissing");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_NOTIFICATION_STOP_DISMISSING);
|
||||
}
|
||||
|
||||
public void onCameraOn() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onCameraOn");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_CAMERA_ON);
|
||||
}
|
||||
|
||||
public void onLeftAffordanceOn() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onLeftAffordanceOn");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_LEFT_AFFORDANCE_ON);
|
||||
}
|
||||
|
||||
public void onAffordanceSwipingStarted(boolean rightCorner) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onAffordanceSwipingStarted");
|
||||
}
|
||||
mCornerSwiping = true;
|
||||
if (rightCorner) {
|
||||
addEvent(PhoneEvent.ON_RIGHT_AFFORDANCE_SWIPING_STARTED);
|
||||
} else {
|
||||
addEvent(PhoneEvent.ON_LEFT_AFFORDANCE_SWIPING_STARTED);
|
||||
}
|
||||
}
|
||||
|
||||
public void onAffordanceSwipingAborted() {
|
||||
if (mCornerSwiping) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onAffordanceSwipingAborted");
|
||||
}
|
||||
mCornerSwiping = false;
|
||||
addEvent(PhoneEvent.ON_AFFORDANCE_SWIPING_ABORTED);
|
||||
}
|
||||
}
|
||||
|
||||
public void onUnlockHintStarted() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onUnlockHintStarted");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_UNLOCK_HINT_STARTED);
|
||||
}
|
||||
|
||||
public void onCameraHintStarted() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onCameraHintStarted");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_CAMERA_HINT_STARTED);
|
||||
}
|
||||
|
||||
public void onLeftAffordanceHintStarted() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onLeftAffordanceHintStarted");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_LEFT_AFFORDANCE_HINT_STARTED);
|
||||
}
|
||||
|
||||
public void onTouchEvent(MotionEvent ev, int width, int height) {
|
||||
if (!mBouncerOn && mCurrentSession != null) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "onTouchEvent(ev.action="
|
||||
+ MotionEvent.actionToString(ev.getAction()) + ")");
|
||||
}
|
||||
mCurrentSession.addMotionEvent(ev);
|
||||
mCurrentSession.setTouchArea(width, height);
|
||||
enforceTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
private void addEvent(int eventType) {
|
||||
if (mEnableAnalytics && mCurrentSession != null) {
|
||||
mCurrentSession.addPhoneEvent(eventType, System.nanoTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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.TouchEvent;
|
||||
import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.SensorEvent;
|
||||
import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.PhoneEvent;
|
||||
|
||||
/**
|
||||
* 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 end(long endTimestampMillis, int result) {
|
||||
mResult = result;
|
||||
mEndTimestampMillis = endTimestampMillis;
|
||||
|
||||
if (LockedPhoneAnalytics.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;
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.ViewMediatorCallback;
|
||||
import com.android.systemui.SystemUI;
|
||||
import com.android.systemui.statusbar.phone.FingerprintUnlockController;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
import com.android.systemui.statusbar.phone.ScrimController;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
@@ -1240,6 +1241,7 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
case START_KEYGUARD_EXIT_ANIM:
|
||||
StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj;
|
||||
handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration);
|
||||
LockedPhoneAnalytics.getInstance(mContext).onSucccessfulUnlock();
|
||||
break;
|
||||
case KEYGUARD_DONE_PENDING_TIMEOUT:
|
||||
Log.w(TAG, "Timeout while waiting for activity drawn!");
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.view.animation.LinearInterpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
|
||||
/**
|
||||
* Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
|
||||
@@ -128,6 +129,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
private final int mNormalColor;
|
||||
private final int mLowPriorityColor;
|
||||
private boolean mIsBelowSpeedBump;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
|
||||
public ActivatableNotificationView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -151,6 +153,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
R.color.notification_ripple_color_low_priority);
|
||||
mNormalRippleColor = context.getColor(
|
||||
R.color.notification_ripple_untinted_color);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -219,6 +222,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
makeActive();
|
||||
postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
|
||||
} else {
|
||||
mLockedPhoneAnalytics.onNotificationDoubleTap();
|
||||
boolean performed = performClick();
|
||||
if (performed) {
|
||||
removeCallbacks(mTapTimeoutRunnable);
|
||||
@@ -238,6 +242,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
}
|
||||
|
||||
private void makeActive() {
|
||||
mLockedPhoneAnalytics.onNotificationActive();
|
||||
startActivateAnimation(false /* reverse */);
|
||||
mActivated = true;
|
||||
if (mOnActivatedListener != null) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.view.animation.Interpolator;
|
||||
import com.android.systemui.ExpandHelper;
|
||||
import com.android.systemui.Gefingerpoken;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
|
||||
/**
|
||||
* A utility class to enable the downward swipe on the lockscreen to go to the full shade and expand
|
||||
@@ -54,6 +55,7 @@ public class DragDownHelper implements Gefingerpoken {
|
||||
private ExpandableView mStartingChild;
|
||||
private Interpolator mInterpolator;
|
||||
private float mLastHeight;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
|
||||
public DragDownHelper(Context context, View host, ExpandHelper.Callback callback,
|
||||
DragDownCallback dragDownCallback) {
|
||||
@@ -65,6 +67,7 @@ public class DragDownHelper implements Gefingerpoken {
|
||||
mCallback = callback;
|
||||
mDragDownCallback = dragDownCallback;
|
||||
mHost = host;
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,6 +87,7 @@ public class DragDownHelper implements Gefingerpoken {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
final float h = y - mInitialTouchY;
|
||||
if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) {
|
||||
mLockedPhoneAnalytics.onNotificatonStartDraggingDown();
|
||||
mDraggingDown = true;
|
||||
captureStartingChild(mInitialTouchX, mInitialTouchY);
|
||||
mInitialTouchY = y;
|
||||
@@ -201,6 +205,7 @@ public class DragDownHelper implements Gefingerpoken {
|
||||
}
|
||||
|
||||
private void stopDragging() {
|
||||
mLockedPhoneAnalytics.onNotificatonStopDraggingDown();
|
||||
if (mStartingChild != null) {
|
||||
cancelExpansion(mStartingChild);
|
||||
} else {
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
import com.android.systemui.statusbar.phone.NotificationGroupManager;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
|
||||
@@ -109,6 +110,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
|
||||
!mChildrenExpanded);
|
||||
}
|
||||
};
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
|
||||
public NotificationContentView getPrivateLayout() {
|
||||
return mPrivateLayout;
|
||||
@@ -307,6 +309,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
|
||||
|
||||
public ExpandableNotificationRow(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -494,6 +497,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
|
||||
* @param userExpanded whether the user wants this notification to be expanded
|
||||
*/
|
||||
public void setUserExpanded(boolean userExpanded) {
|
||||
mLockedPhoneAnalytics.setNotificationExpanded();
|
||||
if (userExpanded && !mExpandable) return;
|
||||
final boolean wasExpanded = isExpanded();
|
||||
mHasUserChangedExpansion = true;
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.R;
|
||||
import com.android.keyguard.ViewMediatorCallback;
|
||||
import com.android.systemui.DejankUtils;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
|
||||
import static com.android.keyguard.KeyguardHostView.OnDismissAction;
|
||||
import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
@@ -49,6 +50,7 @@ public class KeyguardBouncer {
|
||||
private ViewGroup mRoot;
|
||||
private boolean mShowingSoon;
|
||||
private int mBouncerPromptReason;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
private KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
@@ -66,9 +68,11 @@ public class KeyguardBouncer {
|
||||
mContainer = container;
|
||||
mWindowManager = windowManager;
|
||||
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(mContext);
|
||||
}
|
||||
|
||||
public void show(boolean resetSecuritySelection) {
|
||||
mLockedPhoneAnalytics.onBouncerShown();
|
||||
ensureView();
|
||||
if (resetSecuritySelection) {
|
||||
// showPrimarySecurityScreen() updates the current security method. This is needed in
|
||||
@@ -128,6 +132,7 @@ public class KeyguardBouncer {
|
||||
}
|
||||
|
||||
public void hide(boolean destroyView) {
|
||||
mLockedPhoneAnalytics.onBouncerHidden();
|
||||
cancelShowRunnable();
|
||||
if (mKeyguardView != null) {
|
||||
mKeyguardView.cancelDismissAction();
|
||||
@@ -157,6 +162,7 @@ public class KeyguardBouncer {
|
||||
public void reset() {
|
||||
cancelShowRunnable();
|
||||
inflateView();
|
||||
mLockedPhoneAnalytics.onBouncerHidden();
|
||||
}
|
||||
|
||||
public void onScreenTurnedOff() {
|
||||
@@ -244,6 +250,7 @@ public class KeyguardBouncer {
|
||||
|
||||
// We need to show it in case it is secure. If not, it will get dismissed in any case.
|
||||
mRoot.setVisibility(View.VISIBLE);
|
||||
mLockedPhoneAnalytics.onBouncerShown();
|
||||
mKeyguardView.requestFocus();
|
||||
mKeyguardView.onResume();
|
||||
return true;
|
||||
|
||||
@@ -56,6 +56,7 @@ import com.android.systemui.statusbar.GestureRecorder;
|
||||
import com.android.systemui.statusbar.KeyguardAffordanceView;
|
||||
import com.android.systemui.statusbar.NotificationData;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
|
||||
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
|
||||
@@ -203,6 +204,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
private int mLastOrientation = -1;
|
||||
private boolean mClosingWithAlphaFadeOut;
|
||||
private boolean mHeadsUpAnimatingAway;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
|
||||
private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() {
|
||||
@Override
|
||||
@@ -219,6 +221,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
public NotificationPanelView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setWillNotDraw(!DEBUG);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
}
|
||||
|
||||
public void setStatusBar(PhoneStatusBar bar) {
|
||||
@@ -820,6 +823,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
private void handleQsDown(MotionEvent event) {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN
|
||||
&& shouldQuickSettingsIntercept(event.getX(), event.getY(), -1)) {
|
||||
mLockedPhoneAnalytics.onQsDown();
|
||||
mQsTracking = true;
|
||||
onQsExpansionStarted();
|
||||
mInitialHeightOnTouch = mQsExpansionHeight;
|
||||
@@ -987,6 +991,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
mQsExpanded = expanded;
|
||||
updateQsState();
|
||||
requestPanelHeightUpdate();
|
||||
mLockedPhoneAnalytics.setQsExpanded(expanded);
|
||||
mNotificationStackScroller.setInterceptDelegateEnabled(expanded);
|
||||
mStatusBar.setQsExpanded(expanded);
|
||||
mQsPanel.setExpanded(expanded);
|
||||
@@ -1313,6 +1318,10 @@ public class NotificationPanelView extends PanelView implements
|
||||
R.string.accessibility_desc_quick_settings));
|
||||
mLastAnnouncementWasQuickSettings = true;
|
||||
}
|
||||
if (mQsFullyExpanded && mLockedPhoneAnalytics.shouldEnforceBouncer()) {
|
||||
mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
|
||||
false /* dismissShade */, true /* afterKeyguardGone */);
|
||||
}
|
||||
if (DEBUG) {
|
||||
invalidate();
|
||||
}
|
||||
@@ -1840,6 +1849,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
protected void onTrackingStarted() {
|
||||
mLockedPhoneAnalytics.onTrackingStarted();
|
||||
super.onTrackingStarted();
|
||||
if (mQsFullyExpanded) {
|
||||
mQsExpandImmediate = true;
|
||||
@@ -1853,6 +1863,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
protected void onTrackingStopped(boolean expand) {
|
||||
mLockedPhoneAnalytics.onTrackingStopped();
|
||||
super.onTrackingStopped(expand);
|
||||
if (expand) {
|
||||
mNotificationStackScroller.setOverScrolledPixels(
|
||||
@@ -1951,11 +1962,35 @@ public class NotificationPanelView extends PanelView implements
|
||||
if (start) {
|
||||
EventLogTags.writeSysuiLockscreenGesture(
|
||||
EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER, lengthDp, velocityDp);
|
||||
mKeyguardBottomArea.launchLeftAffordance();
|
||||
|
||||
mLockedPhoneAnalytics.onLeftAffordanceOn();
|
||||
if (mLockedPhoneAnalytics.shouldEnforceBouncer()) {
|
||||
mStatusBar.executeRunnableDismissingKeyguard(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mKeyguardBottomArea.launchLeftAffordance();
|
||||
}
|
||||
}, null, true /* dismissShade */, false /* afterKeyguardGone */);
|
||||
}
|
||||
else {
|
||||
mKeyguardBottomArea.launchLeftAffordance();
|
||||
}
|
||||
} else {
|
||||
EventLogTags.writeSysuiLockscreenGesture(
|
||||
EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA, lengthDp, velocityDp);
|
||||
mSecureCameraLaunchManager.startSecureCameraLaunch();
|
||||
|
||||
mLockedPhoneAnalytics.onCameraOn();
|
||||
if (mLockedPhoneAnalytics.shouldEnforceBouncer()) {
|
||||
mStatusBar.executeRunnableDismissingKeyguard(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mSecureCameraLaunchManager.startSecureCameraLaunch();
|
||||
}
|
||||
}, null, true /* dismissShade */, false /* afterKeyguardGone */);
|
||||
}
|
||||
else {
|
||||
mSecureCameraLaunchManager.startSecureCameraLaunch();
|
||||
}
|
||||
}
|
||||
mStatusBar.startLaunchTransitionTimeout();
|
||||
mBlockTouches = true;
|
||||
@@ -1999,6 +2034,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
public void onSwipingStarted(boolean rightIcon) {
|
||||
mLockedPhoneAnalytics.onAffordanceSwipingStarted(rightIcon);
|
||||
boolean camera = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? !rightIcon
|
||||
: rightIcon;
|
||||
if (camera) {
|
||||
@@ -2012,6 +2048,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
public void onSwipingAborted() {
|
||||
mLockedPhoneAnalytics.onAffordanceSwipingAborted();
|
||||
mKeyguardBottomArea.unbindCameraPrewarmService(false /* launched */);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ import com.android.systemui.statusbar.ScrimView;
|
||||
import com.android.systemui.statusbar.SignalClusterView;
|
||||
import com.android.systemui.statusbar.SpeedBumpView;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
|
||||
import com.android.systemui.statusbar.policy.AccessibilityController;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
@@ -589,6 +590,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
private HashSet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new HashSet<>();
|
||||
private RankingMap mLatestRankingMap;
|
||||
private boolean mNoAnimationOnNextBarModeChange;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
@@ -636,6 +638,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
notifyUserAboutHiddenNotifications();
|
||||
|
||||
mScreenPinningRequest = new ScreenPinningRequest(mContext);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(mContext);
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
@@ -3762,6 +3765,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
mState = state;
|
||||
mGroupManager.setStatusBarState(state);
|
||||
mLockedPhoneAnalytics.setStatusBarState(state);
|
||||
mStatusBarWindowManager.setStatusBarState(state);
|
||||
updateDozing();
|
||||
}
|
||||
@@ -3783,6 +3787,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
|
||||
public void onUnlockHintStarted() {
|
||||
mLockedPhoneAnalytics.onUnlockHintStarted();
|
||||
mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
|
||||
}
|
||||
|
||||
@@ -3792,14 +3797,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
|
||||
public void onCameraHintStarted() {
|
||||
mLockedPhoneAnalytics.onCameraHintStarted();
|
||||
mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
|
||||
}
|
||||
|
||||
public void onVoiceAssistHintStarted() {
|
||||
mLockedPhoneAnalytics.onLeftAffordanceHintStarted();
|
||||
mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
|
||||
}
|
||||
|
||||
public void onPhoneHintStarted() {
|
||||
mLockedPhoneAnalytics.onLeftAffordanceHintStarted();
|
||||
mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
|
||||
}
|
||||
|
||||
@@ -3874,7 +3882,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
row.setUserExpanded(true);
|
||||
}
|
||||
boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
|
||||
|| !mShowLockscreenNotifications;
|
||||
|| !mShowLockscreenNotifications || mLockedPhoneAnalytics.shouldEnforceBouncer();
|
||||
if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
|
||||
mLeaveOpenOnKeyguardHide = true;
|
||||
showBouncer();
|
||||
@@ -3919,6 +3927,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mDeviceInteractive = false;
|
||||
mWakeUpComingFromTouch = false;
|
||||
mWakeUpTouchLocation = null;
|
||||
mLockedPhoneAnalytics.onScreenOff();
|
||||
mStackScroller.setAnimationsEnabled(false);
|
||||
updateVisibleToUser();
|
||||
}
|
||||
@@ -3928,6 +3937,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mStackScroller.setAnimationsEnabled(true);
|
||||
mNotificationPanel.setTouchDisabled(false);
|
||||
updateVisibleToUser();
|
||||
mLockedPhoneAnalytics.onScreenOn();
|
||||
}
|
||||
|
||||
public void onScreenTurningOn() {
|
||||
@@ -4056,6 +4066,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
|
||||
mNotificationPanel.setTouchDisabled(false);
|
||||
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
|
||||
mLockedPhoneAnalytics.onScreenOnFromTouch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.BaseStatusBar;
|
||||
import com.android.systemui.statusbar.DragDownHelper;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
|
||||
|
||||
|
||||
@@ -55,12 +56,14 @@ public class StatusBarWindowView extends FrameLayout {
|
||||
|
||||
private PhoneStatusBar mService;
|
||||
private final Paint mTransparentSrcPaint = new Paint();
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
|
||||
public StatusBarWindowView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setMotionEventSplittingEnabled(false);
|
||||
mTransparentSrcPaint.setColor(0);
|
||||
mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -197,6 +200,7 @@ public class StatusBarWindowView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
mLockedPhoneAnalytics.onTouchEvent(ev, getWidth(), getHeight());
|
||||
if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {
|
||||
// Disallow new pointers while the brightness mirror is visible. This is so that you
|
||||
// can't touch anything other than the brightness slider while the mirror is showing
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package systemui;
|
||||
|
||||
option java_package = "com.android.systemui.statusbar.phone";
|
||||
option java_outer_classname = "TouchAnalyticsProto";
|
||||
|
||||
message Session {
|
||||
message TouchEvent {
|
||||
message BoundingBox {
|
||||
optional float width = 1;
|
||||
optional float height = 2;
|
||||
}
|
||||
|
||||
enum Action {
|
||||
// Keep in sync with MotionEvent.
|
||||
DOWN = 0;
|
||||
UP = 1;
|
||||
MOVE = 2;
|
||||
CANCEL = 3;
|
||||
OUTSIDE = 4;
|
||||
POINTER_DOWN = 5;
|
||||
POINTER_UP = 6;
|
||||
}
|
||||
|
||||
message Pointer {
|
||||
optional float x = 1;
|
||||
optional float y = 2;
|
||||
optional float size = 3;
|
||||
optional float pressure = 4;
|
||||
optional int32 id = 5;
|
||||
optional float removed_length = 6;
|
||||
optional BoundingBox removed_boundingBox = 7;
|
||||
}
|
||||
|
||||
optional uint64 timeOffsetNanos = 1;
|
||||
optional Action action = 2;
|
||||
optional int32 actionIndex = 3;
|
||||
repeated Pointer pointers = 4;
|
||||
optional bool removed_redacted = 5;
|
||||
optional BoundingBox removed_boundingBox = 6;
|
||||
}
|
||||
|
||||
message SensorEvent {
|
||||
enum Type {
|
||||
ACCELEROMETER = 1;
|
||||
GYROSCOPE = 4;
|
||||
LIGHT = 5;
|
||||
PROXIMITY = 8;
|
||||
ROTATION_VECTOR = 11;
|
||||
}
|
||||
|
||||
optional Type type = 1;
|
||||
optional uint64 timeOffsetNanos = 2;
|
||||
repeated float values = 3;
|
||||
optional uint64 timestamp = 4;
|
||||
}
|
||||
|
||||
message PhoneEvent {
|
||||
enum Type {
|
||||
ON_SCREEN_ON = 0;
|
||||
ON_SCREEN_ON_FROM_TOUCH = 1;
|
||||
ON_SCREEN_OFF = 2;
|
||||
ON_SUCCESSFUL_UNLOCK = 3;
|
||||
ON_BOUNCER_SHOWN = 4;
|
||||
ON_BOUNCER_HIDDEN = 5;
|
||||
ON_QS_DOWN = 6;
|
||||
SET_QS_EXPANDED_TRUE = 7;
|
||||
SET_QS_EXPANDED_FALSE = 8;
|
||||
ON_TRACKING_STARTED = 9;
|
||||
ON_TRACKING_STOPPED = 10;
|
||||
ON_NOTIFICATION_ACTIVE = 11;
|
||||
ON_NOTIFICATION_INACTIVE = 12;
|
||||
ON_NOTIFICATION_DOUBLE_TAP = 13;
|
||||
SET_NOTIFICATION_EXPANDED = 14;
|
||||
RESET_NOTIFICATION_EXPANDED = 15;
|
||||
ON_NOTIFICATION_START_DRAGGING_DOWN = 16;
|
||||
ON_NOTIFICATION_STOP_DRAGGING_DOWN = 17;
|
||||
ON_NOTIFICATION_DISMISSED = 18;
|
||||
ON_NOTIFICATION_START_DISMISSING = 19;
|
||||
ON_NOTIFICATION_STOP_DISMISSING = 20;
|
||||
ON_RIGHT_AFFORDANCE_SWIPING_STARTED = 21;
|
||||
ON_LEFT_AFFORDANCE_SWIPING_STARTED = 22;
|
||||
ON_AFFORDANCE_SWIPING_ABORTED = 23;
|
||||
ON_CAMERA_ON = 24;
|
||||
ON_LEFT_AFFORDANCE_ON = 25;
|
||||
ON_UNLOCK_HINT_STARTED = 26;
|
||||
ON_CAMERA_HINT_STARTED = 27;
|
||||
ON_LEFT_AFFORDANCE_HINT_STARTED = 28;
|
||||
}
|
||||
|
||||
optional Type type = 1;
|
||||
optional uint64 timeOffsetNanos = 2;
|
||||
}
|
||||
|
||||
enum Result {
|
||||
FAILURE = 0;
|
||||
SUCCESS = 1;
|
||||
UNKNOWN = 2;
|
||||
}
|
||||
|
||||
enum Type {
|
||||
RESERVED_1 = 0;
|
||||
RESERVED_2 = 1;
|
||||
RANDOM_WAKEUP = 2;
|
||||
REAL = 3;
|
||||
}
|
||||
|
||||
optional uint64 startTimestampMillis = 1;
|
||||
optional uint64 durationMillis = 2;
|
||||
optional string build = 3;
|
||||
optional Result result = 4;
|
||||
repeated TouchEvent touchEvents = 5;
|
||||
repeated SensorEvent sensorEvents = 6;
|
||||
|
||||
optional int32 touchAreaWidth = 9;
|
||||
optional int32 touchAreaHeight = 10;
|
||||
optional Type type = 11;
|
||||
repeated PhoneEvent phoneEvents = 12;
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import com.android.systemui.statusbar.NotificationOverflowContainer;
|
||||
import com.android.systemui.statusbar.SpeedBumpView;
|
||||
import com.android.systemui.statusbar.StackScrollerDecorView;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
import com.android.systemui.statusbar.phone.NotificationGroupManager;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
import com.android.systemui.statusbar.phone.ScrimController;
|
||||
@@ -231,6 +232,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
private boolean mForceNoOverlappingRendering;
|
||||
private NotificationOverflowContainer mOverflowContainer;
|
||||
private final ArrayList<Pair<ExpandableNotificationRow, Boolean>> mTmpList = new ArrayList<>();
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
|
||||
public NotificationStackScrollLayout(Context context) {
|
||||
this(context, null);
|
||||
@@ -264,6 +266,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
mDebugPaint.setStrokeWidth(2);
|
||||
mDebugPaint.setStyle(Paint.Style.STROKE);
|
||||
}
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -595,6 +598,12 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
veto.performClick();
|
||||
}
|
||||
if (DEBUG) Log.v(TAG, "onChildDismissed: " + v);
|
||||
|
||||
mLockedPhoneAnalytics.onNotificationDismissed();
|
||||
if (mLockedPhoneAnalytics.shouldEnforceBouncer()) {
|
||||
mPhoneStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
|
||||
false /* dismissShade */, true /* afterKeyguardGone */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -622,6 +631,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
|
||||
public void onBeginDrag(View v) {
|
||||
mLockedPhoneAnalytics.onNotificatonStartDismissing();
|
||||
setSwipingInProgress(true);
|
||||
mAmbientState.onBeginDrag(v);
|
||||
if (mAnimationsEnabled && (mIsExpanded || !isPinnedHeadsUp(v))) {
|
||||
@@ -648,6 +658,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
|
||||
public void onDragCancelled(View v) {
|
||||
mLockedPhoneAnalytics.onNotificatonStopDismissing();
|
||||
setSwipingInProgress(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,14 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
|
||||
LOCAL_PROTOC_FLAGS := -I$(LOCAL_PATH)/..
|
||||
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
|
||||
|
||||
LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages com.android.systemui:com.android.keyguard
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
|
||||
$(call all-java-files-under, ../src) \
|
||||
$(call all-proto-files-under, ../src) \
|
||||
src/com/android/systemui/EventLogTags.logtags
|
||||
|
||||
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
|
||||
|
||||
Reference in New Issue
Block a user