Add FalsingManager and Classifier to SystemUI
Adds the possibility to analyze and classify touch and sensor events as human or false touches. Change-Id: I5079c02406d532fea38ca2d302e8606effae0696
This commit is contained in:
@@ -21,7 +21,6 @@ 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;
|
||||
@@ -30,8 +29,6 @@ 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;
|
||||
@@ -47,24 +44,29 @@ import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.P
|
||||
* 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";
|
||||
public class DataCollector implements SensorEventListener {
|
||||
private static final String TAG = "DataCollector";
|
||||
private static final String COLLECTOR_ENABLE = "data_collector_enable";
|
||||
private static final String COLLECT_BAD_TOUCHES = "data_collector_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();
|
||||
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 mEnableCollector = false;
|
||||
private boolean mTimeoutActive = false;
|
||||
private boolean mCollectBadTouches = false;
|
||||
private boolean mCornerSwiping = false;
|
||||
private boolean mTrackingStarted = false;
|
||||
|
||||
private static DataCollector sInstance = null;
|
||||
|
||||
protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
@@ -72,69 +74,40 @@ public class LockedPhoneAnalytics implements SensorEventListener {
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
private DataCollector(Context context) {
|
||||
mContext = context;
|
||||
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Secure.getUriFor(ANALYTICS_ENABLE), false,
|
||||
Settings.Secure.getUriFor(COLLECTOR_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,
|
||||
Settings.Secure.getUriFor(COLLECT_BAD_TOUCHES), false,
|
||||
mSettingsObserver,
|
||||
UserHandle.USER_ALL);
|
||||
|
||||
updateConfiguration();
|
||||
}
|
||||
|
||||
public static LockedPhoneAnalytics getInstance(Context context) {
|
||||
public static DataCollector getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new LockedPhoneAnalytics(context);
|
||||
sInstance = new DataCollector(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private void updateConfiguration() {
|
||||
mEnableAnalytics = Build.IS_DEBUGGABLE && 0 != Settings.Secure.getInt(
|
||||
mEnableCollector = Build.IS_DEBUGGABLE && 0 != Settings.Secure.getInt(
|
||||
mContext.getContentResolver(),
|
||||
ANALYTICS_ENABLE, 0);
|
||||
mEnforceBouncer = mEnableAnalytics && 0 != Settings.Secure.getInt(
|
||||
COLLECTOR_ENABLE, 0);
|
||||
mCollectBadTouches = mEnableCollector && 0 != Settings.Secure.getInt(
|
||||
mContext.getContentResolver(),
|
||||
ENFORCE_BOUNCER, 0);
|
||||
mCollectBadTouches = mEnableAnalytics && 0 != Settings.Secure.getInt(
|
||||
mContext.getContentResolver(),
|
||||
COLLECT_BAD_TOCUHES, 0);
|
||||
COLLECT_BAD_TOUCHES, 0);
|
||||
}
|
||||
|
||||
private boolean sessionEntrypoint() {
|
||||
if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
|
||||
&& mEnableAnalytics && mCurrentSession == null) {
|
||||
if (mEnableCollector && mCurrentSession == null) {
|
||||
onSessionStart();
|
||||
return true;
|
||||
}
|
||||
@@ -142,22 +115,15 @@ public class LockedPhoneAnalytics implements SensorEventListener {
|
||||
}
|
||||
|
||||
private void sessionExitpoint(int result) {
|
||||
if (mEnableAnalytics && mCurrentSession != null) {
|
||||
if (mEnableCollector && 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) {
|
||||
@@ -196,10 +162,9 @@ public class LockedPhoneAnalytics implements SensorEventListener {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void onSensorChanged(SensorEvent event) {
|
||||
if (mEnableAnalytics && mCurrentSession != null) {
|
||||
if (mEnableCollector && mCurrentSession != null) {
|
||||
mCurrentSession.addSensorEvent(event, System.nanoTime());
|
||||
enforceTimeout();
|
||||
}
|
||||
@@ -221,18 +186,14 @@ public class LockedPhoneAnalytics implements SensorEventListener {
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
}
|
||||
|
||||
public boolean shouldEnforceBouncer() {
|
||||
return mEnforceBouncer;
|
||||
public boolean isEnabled() {
|
||||
return mEnableCollector;
|
||||
}
|
||||
|
||||
public void setStatusBarState(int state) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
public void onScreenOn() {
|
||||
public void onScreenTurningOn() {
|
||||
if (sessionEntrypoint()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onScreenOn");
|
||||
Log.d(TAG, "onScreenTurningOn");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_SCREEN_ON);
|
||||
}
|
||||
@@ -264,23 +225,17 @@ public class LockedPhoneAnalytics implements SensorEventListener {
|
||||
}
|
||||
|
||||
public void onBouncerShown() {
|
||||
if (!mBouncerOn) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBouncerShown");
|
||||
}
|
||||
mBouncerOn = true;
|
||||
addEvent(PhoneEvent.ON_BOUNCER_SHOWN);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBouncerShown");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_BOUNCER_SHOWN);
|
||||
}
|
||||
|
||||
public void onBouncerHidden() {
|
||||
if (mBouncerOn) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBouncerHidden");
|
||||
}
|
||||
mBouncerOn = false;
|
||||
addEvent(PhoneEvent.ON_BOUNCER_HIDDEN);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBouncerHidden");
|
||||
}
|
||||
addEvent(PhoneEvent.ON_BOUNCER_HIDDEN);
|
||||
}
|
||||
|
||||
public void onQsDown() {
|
||||
@@ -433,20 +388,20 @@ public class LockedPhoneAnalytics implements SensorEventListener {
|
||||
addEvent(PhoneEvent.ON_LEFT_AFFORDANCE_HINT_STARTED);
|
||||
}
|
||||
|
||||
public void onTouchEvent(MotionEvent ev, int width, int height) {
|
||||
if (!mBouncerOn && mCurrentSession != null) {
|
||||
public void onTouchEvent(MotionEvent event, int width, int height) {
|
||||
if (mCurrentSession != null) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "onTouchEvent(ev.action="
|
||||
+ MotionEvent.actionToString(ev.getAction()) + ")");
|
||||
+ MotionEvent.actionToString(event.getAction()) + ")");
|
||||
}
|
||||
mCurrentSession.addMotionEvent(ev);
|
||||
mCurrentSession.addMotionEvent(event);
|
||||
mCurrentSession.setTouchArea(width, height);
|
||||
enforceTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
private void addEvent(int eventType) {
|
||||
if (mEnableAnalytics && mCurrentSession != null) {
|
||||
if (mEnableCollector && mCurrentSession != null) {
|
||||
mCurrentSession.addPhoneEvent(eventType, System.nanoTime());
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public class SensorLoggerSession {
|
||||
mResult = result;
|
||||
mEndTimestampMillis = endTimestampMillis;
|
||||
|
||||
if (LockedPhoneAnalytics.DEBUG) {
|
||||
if (DataCollector.DEBUG) {
|
||||
Log.d(TAG, "Ending session result=" + result + " it lasted for " +
|
||||
(float) (mEndTimestampMillis - mStartTimestampMillis) / 1000f + "s");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.classifier;
|
||||
|
||||
import android.hardware.SensorEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.lang.Math;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A classifier which calculates the variance of differences between successive angles in a stroke.
|
||||
* For each stroke it keeps its last three points. If some successive points are the same, it ignores
|
||||
* the repetitions. If a new point is added, the classifier calculates the angle between the last
|
||||
* three points. After that it calculates the difference between this angle and the previously
|
||||
* calculated angle. The return value of the classifier is the variance of the differences
|
||||
* from a stroke. If there are multiple strokes created at once, the classifier sums up the
|
||||
* variances of all the strokes. Also the value is multiplied by HISTORY_FACTOR after each
|
||||
* INTERVAL milliseconds.
|
||||
*/
|
||||
public class AnglesVarianceClassifier extends Classifier {
|
||||
private final float INTERVAL = 10.0f;
|
||||
private final float CLEAR_HISTORY = 500f;
|
||||
private final float HISTORY_FACTOR = 0.9f;
|
||||
|
||||
private HashMap<Stroke, Data> mStrokeMap = new HashMap<>();
|
||||
private float mValue;
|
||||
private long mLastUpdate;
|
||||
|
||||
public AnglesVarianceClassifier(ClassifierData classifierData) {
|
||||
mClassifierData = classifierData;
|
||||
mValue = 0.0f;
|
||||
mLastUpdate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTouchEvent(MotionEvent event) {
|
||||
int action = event.getActionMasked();
|
||||
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
mStrokeMap.clear();
|
||||
}
|
||||
|
||||
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||
Stroke stroke = mClassifierData.getStroke(event.getPointerId(i));
|
||||
|
||||
if (mStrokeMap.get(stroke) == null) {
|
||||
mStrokeMap.put(stroke, new Data());
|
||||
}
|
||||
mStrokeMap.get(stroke).addPoint(stroke.getPoints().get(stroke.getPoints().size() - 1));
|
||||
|
||||
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL
|
||||
|| (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) {
|
||||
decayValue();
|
||||
mValue += mStrokeMap.get(stroke).getAnglesVariance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decreases mValue through time
|
||||
*/
|
||||
private void decayValue() {
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
if (currentTimeMillis - mLastUpdate > CLEAR_HISTORY) {
|
||||
mValue = 0.0f;
|
||||
} else {
|
||||
mValue *= Math.pow(HISTORY_FACTOR, (float) (currentTimeMillis - mLastUpdate) / INTERVAL);
|
||||
}
|
||||
mLastUpdate = currentTimeMillis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFalseTouchEvaluation(int type) {
|
||||
decayValue();
|
||||
float currentValue = 0.0f;
|
||||
for (Data data: mStrokeMap.values()) {
|
||||
currentValue += data.getAnglesVariance();
|
||||
}
|
||||
return (float) (mValue + currentValue);
|
||||
}
|
||||
|
||||
private class Data {
|
||||
private List<Point> mLastThreePoints = new ArrayList<>();
|
||||
private float mPreviousAngle;
|
||||
private float mSumSquares;
|
||||
private float mSum;
|
||||
private float mCount;
|
||||
|
||||
public Data() {
|
||||
mPreviousAngle = (float) Math.PI;
|
||||
mSumSquares = 0.0f;
|
||||
mSum = 0.0f;
|
||||
mCount = 1.0f;
|
||||
}
|
||||
|
||||
public void addPoint(Point point) {
|
||||
// Checking if the added point is different than the previously added point
|
||||
// Repetitions are being ignored so that proper angles are calculated.
|
||||
if (mLastThreePoints.isEmpty()
|
||||
|| !mLastThreePoints.get(mLastThreePoints.size() - 1).equals(point)) {
|
||||
mLastThreePoints.add(point);
|
||||
if (mLastThreePoints.size() == 4) {
|
||||
mLastThreePoints.remove(0);
|
||||
|
||||
float angle = getAngle(mLastThreePoints.get(0), mLastThreePoints.get(1),
|
||||
mLastThreePoints.get(2));
|
||||
|
||||
float difference = angle - mPreviousAngle;
|
||||
mSum += difference;
|
||||
mSumSquares += difference * difference;
|
||||
mCount += 1.0;
|
||||
mPreviousAngle = angle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float getAngle(Point a, Point b, Point c) {
|
||||
float dist1 = a.dist(b);
|
||||
float dist2 = b.dist(c);
|
||||
float crossProduct = b.crossProduct(a, c);
|
||||
float dotProduct = b.dotProduct(a, c);
|
||||
float cos = Math.min(1.0f, Math.max(-1.0f, dotProduct / dist1 / dist2));
|
||||
float angle = (float) Math.acos(cos);
|
||||
if (crossProduct < 0.0) {
|
||||
angle = 2.0f * (float) Math.PI - angle;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
public float getAnglesVariance() {
|
||||
return mSumSquares / mCount + (mSum / mCount) * (mSum / mCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.classifier;
|
||||
|
||||
import android.hardware.SensorEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* An interface for classifiers for touch and sensor events.
|
||||
*/
|
||||
public abstract class Classifier {
|
||||
public static final int QUICK_SETTINGS = 0;
|
||||
public static final int NOTIFICATION_DISMISS = 1;
|
||||
public static final int NOTIFICATION_DRAG_DOWN = 2;
|
||||
public static final int NOTIFICATION_DOUBLE_TAP = 3;
|
||||
public static final int UNLOCK = 4;
|
||||
public static final int LEFT_AFFORDANCE = 5;
|
||||
public static final int RIGHT_AFFORDANCE = 6;
|
||||
|
||||
/**
|
||||
* Contains all the information about touch events from which the classifier can query
|
||||
*/
|
||||
protected ClassifierData mClassifierData;
|
||||
|
||||
/**
|
||||
* Informs the classifier that a new touch event has occurred
|
||||
*/
|
||||
public void onTouchEvent(MotionEvent event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the classifier that a sensor change occurred
|
||||
*/
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type the type of action for which this method is called
|
||||
* @return a nonnegative value which is used to determine whether this a false touch. The
|
||||
* bigger the value the greater the chance that this a false touch.
|
||||
*/
|
||||
public abstract float getFalseTouchEvaluation(int type);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.classifier;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* Contains data which is used to classify interaction sequences on the lockscreen. It does, for
|
||||
* example, provide information on the current touch state.
|
||||
*/
|
||||
public class ClassifierData {
|
||||
private SparseArray<Stroke> mCurrentStrokes = new SparseArray<>();
|
||||
|
||||
public ClassifierData() {
|
||||
}
|
||||
|
||||
public void update(MotionEvent event) {
|
||||
int action = event.getActionMasked();
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
mCurrentStrokes.clear();
|
||||
}
|
||||
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||
int id = event.getPointerId(i);
|
||||
if (mCurrentStrokes.get(id) == null) {
|
||||
mCurrentStrokes.put(id, new Stroke(event.getEventTimeNano()));
|
||||
}
|
||||
mCurrentStrokes.get(id).addPoint(event.getX(i), event.getY(i),
|
||||
event.getEventTimeNano());
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanUp(MotionEvent event) {
|
||||
int action = event.getActionMasked();
|
||||
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||
int id = event.getPointerId(i);
|
||||
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL
|
||||
|| (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) {
|
||||
mCurrentStrokes.remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id from MotionEvent
|
||||
* @return the Stroke assigned to the id
|
||||
*/
|
||||
public Stroke getStroke(int id) {
|
||||
return mCurrentStrokes.get(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* 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.classifier;
|
||||
|
||||
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.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.systemui.analytics.DataCollector;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
|
||||
/**
|
||||
* When the phone is locked, listens to touch, sensor and phone events and sends them to
|
||||
* DataCollector and HumanInteractionClassifier.
|
||||
*
|
||||
* It does not collect touch events when the bouncer shows up.
|
||||
*/
|
||||
public class FalsingManager implements SensorEventListener {
|
||||
private static final String ENFORCE_BOUNCER = "falsing_manager_enforce_bouncer";
|
||||
|
||||
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();
|
||||
private final Context mContext;
|
||||
|
||||
private final SensorManager mSensorManager;
|
||||
private final DataCollector mDataCollector;
|
||||
private final HumanInteractionClassifier mHumanInteractionClassifier;
|
||||
|
||||
private static FalsingManager sInstance = null;
|
||||
|
||||
private boolean mEnforceBouncer = false;
|
||||
private boolean mBouncerOn = false;
|
||||
private boolean mSessionActive = false;
|
||||
private int mState = StatusBarState.SHADE;
|
||||
|
||||
protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateConfiguration();
|
||||
}
|
||||
};
|
||||
|
||||
private FalsingManager(Context context) {
|
||||
mContext = context;
|
||||
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
|
||||
mDataCollector = DataCollector.getInstance(mContext);
|
||||
mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
|
||||
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Secure.getUriFor(ENFORCE_BOUNCER), false,
|
||||
mSettingsObserver,
|
||||
UserHandle.USER_ALL);
|
||||
|
||||
updateConfiguration();
|
||||
}
|
||||
|
||||
public static FalsingManager getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new FalsingManager(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private void updateConfiguration() {
|
||||
mEnforceBouncer = 0 != Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
ENFORCE_BOUNCER, 0);
|
||||
}
|
||||
|
||||
private boolean sessionEntrypoint() {
|
||||
if (!mSessionActive && isEnabled() &&
|
||||
(mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
|
||||
onSessionStart();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void sessionExitpoint() {
|
||||
if (mSessionActive) {
|
||||
mSessionActive = false;
|
||||
mSensorManager.unregisterListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void onSessionStart() {
|
||||
mBouncerOn = false;
|
||||
mSessionActive = true;
|
||||
for (int sensorType : SENSORS) {
|
||||
Sensor s = mSensorManager.getDefaultSensor(sensorType);
|
||||
if (s != null) {
|
||||
mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
return mHumanInteractionClassifier.isEnabled() || mDataCollector.isEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type the type of action for which this method is called
|
||||
* @return true if the classifier determined that this is not a human interacting with the phone
|
||||
*/
|
||||
public boolean isFalseTouch(int type) {
|
||||
return mHumanInteractionClassifier.getFalseTouchEvaluation(type) > 0.5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onSensorChanged(SensorEvent event) {
|
||||
mDataCollector.onSensorChanged(event);
|
||||
mHumanInteractionClassifier.onSensorChanged(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
mDataCollector.onAccuracyChanged(sensor, accuracy);
|
||||
}
|
||||
|
||||
public boolean shouldEnforceBouncer() {
|
||||
return mEnforceBouncer;
|
||||
}
|
||||
|
||||
public void setStatusBarState(int state) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
public void onScreenTurningOn() {
|
||||
if (sessionEntrypoint()) {
|
||||
mDataCollector.onScreenTurningOn();
|
||||
}
|
||||
}
|
||||
|
||||
public void onScreenOnFromTouch() {
|
||||
if (sessionEntrypoint()) {
|
||||
mDataCollector.onScreenOnFromTouch();
|
||||
}
|
||||
}
|
||||
|
||||
public void onScreenOff() {
|
||||
mDataCollector.onScreenOff();
|
||||
sessionExitpoint();
|
||||
}
|
||||
|
||||
public void onSucccessfulUnlock() {
|
||||
mDataCollector.onSucccessfulUnlock();
|
||||
sessionExitpoint();
|
||||
}
|
||||
|
||||
public void onBouncerShown() {
|
||||
if (!mBouncerOn) {
|
||||
mBouncerOn = true;
|
||||
mDataCollector.onBouncerShown();
|
||||
}
|
||||
}
|
||||
|
||||
public void onBouncerHidden() {
|
||||
if (mBouncerOn) {
|
||||
mBouncerOn = false;
|
||||
mDataCollector.onBouncerHidden();
|
||||
}
|
||||
}
|
||||
|
||||
public void onQsDown() {
|
||||
mDataCollector.onQsDown();
|
||||
}
|
||||
|
||||
public void setQsExpanded(boolean expanded) {
|
||||
mDataCollector.setQsExpanded(expanded);
|
||||
}
|
||||
|
||||
public void onTrackingStarted() {
|
||||
mDataCollector.onTrackingStarted();
|
||||
}
|
||||
|
||||
public void onTrackingStopped() {
|
||||
mDataCollector.onTrackingStopped();
|
||||
}
|
||||
|
||||
public void onNotificationActive() {
|
||||
mDataCollector.onNotificationActive();
|
||||
}
|
||||
|
||||
public void onNotificationDoubleTap() {
|
||||
mDataCollector.onNotificationDoubleTap();
|
||||
}
|
||||
|
||||
public void setNotificationExpanded() {
|
||||
mDataCollector.setNotificationExpanded();
|
||||
}
|
||||
|
||||
public void onNotificatonStartDraggingDown() {
|
||||
mDataCollector.onNotificatonStartDraggingDown();
|
||||
}
|
||||
|
||||
public void onNotificatonStopDraggingDown() {
|
||||
mDataCollector.onNotificatonStopDraggingDown();
|
||||
}
|
||||
|
||||
public void onNotificationDismissed() {
|
||||
mDataCollector.onNotificationDismissed();
|
||||
}
|
||||
|
||||
public void onNotificatonStartDismissing() {
|
||||
mDataCollector.onNotificatonStartDismissing();
|
||||
}
|
||||
|
||||
public void onNotificatonStopDismissing() {
|
||||
mDataCollector.onNotificatonStopDismissing();
|
||||
}
|
||||
|
||||
public void onCameraOn() {
|
||||
mDataCollector.onCameraOn();
|
||||
}
|
||||
|
||||
public void onLeftAffordanceOn() {
|
||||
mDataCollector.onLeftAffordanceOn();
|
||||
}
|
||||
|
||||
public void onAffordanceSwipingStarted(boolean rightCorner) {
|
||||
mDataCollector.onAffordanceSwipingStarted(rightCorner);
|
||||
}
|
||||
|
||||
public void onAffordanceSwipingAborted() {
|
||||
mDataCollector.onAffordanceSwipingAborted();
|
||||
}
|
||||
|
||||
public void onUnlockHintStarted() {
|
||||
mDataCollector.onUnlockHintStarted();
|
||||
}
|
||||
|
||||
public void onCameraHintStarted() {
|
||||
mDataCollector.onCameraHintStarted();
|
||||
}
|
||||
|
||||
public void onLeftAffordanceHintStarted() {
|
||||
mDataCollector.onLeftAffordanceHintStarted();
|
||||
}
|
||||
|
||||
public void onTouchEvent(MotionEvent event, int width, int height) {
|
||||
if (mSessionActive && !mBouncerOn) {
|
||||
mDataCollector.onTouchEvent(event, width, height);
|
||||
mHumanInteractionClassifier.onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.classifier;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* An classifier trying to determine whether it is a human interacting with the phone or not.
|
||||
*/
|
||||
public class HumanInteractionClassifier extends Classifier {
|
||||
private static final String HIC_ENABLE = "HIC_enable";
|
||||
private static HumanInteractionClassifier sInstance = null;
|
||||
|
||||
private final Handler mHandler = new Handler();
|
||||
private final Context mContext;
|
||||
|
||||
private AnglesVarianceClassifier mAnglesVarianceClassifier;
|
||||
private boolean mEnableClassifier = false;
|
||||
|
||||
protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateConfiguration();
|
||||
}
|
||||
};
|
||||
|
||||
private HumanInteractionClassifier(Context context) {
|
||||
mContext = context;
|
||||
mClassifierData = new ClassifierData();
|
||||
mAnglesVarianceClassifier = new AnglesVarianceClassifier(mClassifierData);
|
||||
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(HIC_ENABLE), false,
|
||||
mSettingsObserver,
|
||||
UserHandle.USER_ALL);
|
||||
|
||||
updateConfiguration();
|
||||
}
|
||||
|
||||
public static HumanInteractionClassifier getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new HumanInteractionClassifier(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private void updateConfiguration() {
|
||||
mEnableClassifier = Build.IS_DEBUGGABLE && 0 != Settings.Global.getInt(
|
||||
mContext.getContentResolver(),
|
||||
HIC_ENABLE, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTouchEvent(MotionEvent event) {
|
||||
if (mEnableClassifier) {
|
||||
mClassifierData.update(event);
|
||||
mAnglesVarianceClassifier.onTouchEvent(event);
|
||||
mClassifierData.cleanUp(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFalseTouchEvaluation(int type) {
|
||||
if (mEnableClassifier) {
|
||||
return mAnglesVarianceClassifier.getFalseTouchEvaluation(type);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return mEnableClassifier;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.classifier;
|
||||
|
||||
public class Point {
|
||||
public float x;
|
||||
public float y;
|
||||
public long timeOffsetNano;
|
||||
|
||||
public Point(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.timeOffsetNano = 0;
|
||||
}
|
||||
|
||||
public Point(float x, float y, long timeOffsetNano) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.timeOffsetNano = timeOffsetNano;
|
||||
}
|
||||
|
||||
public boolean equals(Point p) {
|
||||
return x == p.x && y == p.y;
|
||||
}
|
||||
|
||||
public float dist(Point a) {
|
||||
return (float) Math.hypot(a.x - x, a.y - y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the cross product of vec(this, a) and vec(this, b) where vec(x,y) is the
|
||||
* vector from point x to point y
|
||||
*/
|
||||
public float crossProduct(Point a, Point b) {
|
||||
return (a.x - x) * (b.y - y) - (a.y - y) * (b.x - x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the dot product of vec(this, a) and vec(this, b) where vec(x,y) is the
|
||||
* vector from point x to point y
|
||||
*/
|
||||
public float dotProduct(Point a, Point b) {
|
||||
return (a.x - x) * (b.x - x) + (a.y - y) * (b.y - y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.classifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Contains data about movement traces (pointers)
|
||||
*/
|
||||
public class Stroke {
|
||||
private ArrayList<Point> mPoints = new ArrayList<>();
|
||||
private long mStartTimeNano;
|
||||
private long mEndTimeNano;
|
||||
|
||||
public Stroke(long eventTimeNano) {
|
||||
mStartTimeNano = mEndTimeNano = eventTimeNano;
|
||||
}
|
||||
|
||||
public void addPoint(float x, float y, long eventTimeNano) {
|
||||
mEndTimeNano = eventTimeNano;
|
||||
mPoints.add(new Point(x, y, eventTimeNano - mStartTimeNano));
|
||||
}
|
||||
|
||||
public ArrayList<Point> getPoints() {
|
||||
return mPoints;
|
||||
}
|
||||
}
|
||||
@@ -68,8 +68,8 @@ import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.ViewMediatorCallback;
|
||||
import com.android.systemui.SystemUI;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
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;
|
||||
@@ -1244,7 +1244,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();
|
||||
FalsingManager.getInstance(mContext).onSucccessfulUnlock();
|
||||
break;
|
||||
case KEYGUARD_DONE_PENDING_TIMEOUT:
|
||||
Log.w(TAG, "Timeout while waiting for activity drawn!");
|
||||
|
||||
@@ -34,7 +34,7 @@ import android.view.animation.LinearInterpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.analytics.LockedPhoneAnalytics;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
|
||||
/**
|
||||
* Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
|
||||
@@ -129,7 +129,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
private final int mNormalColor;
|
||||
private final int mLowPriorityColor;
|
||||
private boolean mIsBelowSpeedBump;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
private FalsingManager mFalsingManager;
|
||||
|
||||
public ActivatableNotificationView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -153,7 +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);
|
||||
mFalsingManager = FalsingManager.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -222,7 +222,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
makeActive();
|
||||
postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
|
||||
} else {
|
||||
mLockedPhoneAnalytics.onNotificationDoubleTap();
|
||||
mFalsingManager.onNotificationDoubleTap();
|
||||
boolean performed = performClick();
|
||||
if (performed) {
|
||||
removeCallbacks(mTapTimeoutRunnable);
|
||||
@@ -242,7 +242,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
}
|
||||
|
||||
private void makeActive() {
|
||||
mLockedPhoneAnalytics.onNotificationActive();
|
||||
mFalsingManager.onNotificationActive();
|
||||
startActivateAnimation(false /* reverse */);
|
||||
mActivated = true;
|
||||
if (mOnActivatedListener != null) {
|
||||
|
||||
@@ -29,7 +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;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
|
||||
/**
|
||||
* A utility class to enable the downward swipe on the lockscreen to go to the full shade and expand
|
||||
@@ -55,7 +55,7 @@ public class DragDownHelper implements Gefingerpoken {
|
||||
private ExpandableView mStartingChild;
|
||||
private Interpolator mInterpolator;
|
||||
private float mLastHeight;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
private FalsingManager mFalsingManager;
|
||||
|
||||
public DragDownHelper(Context context, View host, ExpandHelper.Callback callback,
|
||||
DragDownCallback dragDownCallback) {
|
||||
@@ -67,7 +67,7 @@ public class DragDownHelper implements Gefingerpoken {
|
||||
mCallback = callback;
|
||||
mDragDownCallback = dragDownCallback;
|
||||
mHost = host;
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
mFalsingManager = FalsingManager.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,7 +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();
|
||||
mFalsingManager.onNotificatonStartDraggingDown();
|
||||
mDraggingDown = true;
|
||||
captureStartingChild(mInitialTouchX, mInitialTouchY);
|
||||
mInitialTouchY = y;
|
||||
@@ -205,7 +205,7 @@ public class DragDownHelper implements Gefingerpoken {
|
||||
}
|
||||
|
||||
private void stopDragging() {
|
||||
mLockedPhoneAnalytics.onNotificatonStopDraggingDown();
|
||||
mFalsingManager.onNotificatonStopDraggingDown();
|
||||
if (mStartingChild != null) {
|
||||
cancelExpansion(mStartingChild);
|
||||
} else {
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
@@ -35,7 +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.classifier.FalsingManager;
|
||||
import com.android.systemui.statusbar.phone.NotificationGroupManager;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
|
||||
@@ -111,7 +110,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
|
||||
!mChildrenExpanded);
|
||||
}
|
||||
};
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
private FalsingManager mFalsingManager;
|
||||
|
||||
private boolean mJustClicked;
|
||||
|
||||
@@ -327,7 +326,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
|
||||
|
||||
public ExpandableNotificationRow(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
mFalsingManager = FalsingManager.getInstance(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -515,7 +514,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
|
||||
* @param userExpanded whether the user wants this notification to be expanded
|
||||
*/
|
||||
public void setUserExpanded(boolean userExpanded) {
|
||||
mLockedPhoneAnalytics.setNotificationExpanded();
|
||||
mFalsingManager.setNotificationExpanded();
|
||||
if (userExpanded && !mExpandable) return;
|
||||
final boolean wasExpanded = isExpanded();
|
||||
mHasUserChangedExpansion = true;
|
||||
|
||||
@@ -31,7 +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 com.android.systemui.classifier.FalsingManager;
|
||||
|
||||
import static com.android.keyguard.KeyguardHostView.OnDismissAction;
|
||||
import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
@@ -50,7 +50,7 @@ public class KeyguardBouncer {
|
||||
private ViewGroup mRoot;
|
||||
private boolean mShowingSoon;
|
||||
private int mBouncerPromptReason;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
private FalsingManager mFalsingManager;
|
||||
private KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
@@ -68,11 +68,11 @@ public class KeyguardBouncer {
|
||||
mContainer = container;
|
||||
mWindowManager = windowManager;
|
||||
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(mContext);
|
||||
mFalsingManager = FalsingManager.getInstance(mContext);
|
||||
}
|
||||
|
||||
public void show(boolean resetSecuritySelection) {
|
||||
mLockedPhoneAnalytics.onBouncerShown();
|
||||
mFalsingManager.onBouncerShown();
|
||||
ensureView();
|
||||
if (resetSecuritySelection) {
|
||||
// showPrimarySecurityScreen() updates the current security method. This is needed in
|
||||
@@ -132,7 +132,7 @@ public class KeyguardBouncer {
|
||||
}
|
||||
|
||||
public void hide(boolean destroyView) {
|
||||
mLockedPhoneAnalytics.onBouncerHidden();
|
||||
mFalsingManager.onBouncerHidden();
|
||||
cancelShowRunnable();
|
||||
if (mKeyguardView != null) {
|
||||
mKeyguardView.cancelDismissAction();
|
||||
@@ -162,7 +162,7 @@ public class KeyguardBouncer {
|
||||
public void reset() {
|
||||
cancelShowRunnable();
|
||||
inflateView();
|
||||
mLockedPhoneAnalytics.onBouncerHidden();
|
||||
mFalsingManager.onBouncerHidden();
|
||||
}
|
||||
|
||||
public void onScreenTurnedOff() {
|
||||
@@ -250,7 +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();
|
||||
mFalsingManager.onBouncerShown();
|
||||
mKeyguardView.requestFocus();
|
||||
mKeyguardView.onResume();
|
||||
return true;
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
@@ -50,6 +49,7 @@ import com.android.systemui.DejankUtils;
|
||||
import com.android.systemui.EventLogConstants;
|
||||
import com.android.systemui.EventLogTags;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
import com.android.systemui.qs.QSContainer;
|
||||
import com.android.systemui.qs.QSPanel;
|
||||
import com.android.systemui.statusbar.ExpandableNotificationRow;
|
||||
@@ -59,7 +59,6 @@ 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;
|
||||
@@ -204,7 +203,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
private boolean mClosingWithAlphaFadeOut;
|
||||
private boolean mHeadsUpAnimatingAway;
|
||||
private boolean mLaunchingAffordance;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
private FalsingManager mFalsingManager;
|
||||
|
||||
private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() {
|
||||
@Override
|
||||
@@ -221,7 +220,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
public NotificationPanelView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setWillNotDraw(!DEBUG);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
mFalsingManager = FalsingManager.getInstance(context);
|
||||
}
|
||||
|
||||
public void setStatusBar(PhoneStatusBar bar) {
|
||||
@@ -813,7 +812,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();
|
||||
mFalsingManager.onQsDown();
|
||||
mQsTracking = true;
|
||||
onQsExpansionStarted();
|
||||
mInitialHeightOnTouch = mQsExpansionHeight;
|
||||
@@ -981,7 +980,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
mQsExpanded = expanded;
|
||||
updateQsState();
|
||||
requestPanelHeightUpdate();
|
||||
mLockedPhoneAnalytics.setQsExpanded(expanded);
|
||||
mFalsingManager.setQsExpanded(expanded);
|
||||
mNotificationStackScroller.setInterceptDelegateEnabled(expanded);
|
||||
mStatusBar.setQsExpanded(expanded);
|
||||
mQsPanel.setExpanded(expanded);
|
||||
@@ -1308,7 +1307,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
R.string.accessibility_desc_quick_settings));
|
||||
mLastAnnouncementWasQuickSettings = true;
|
||||
}
|
||||
if (mQsFullyExpanded && mLockedPhoneAnalytics.shouldEnforceBouncer()) {
|
||||
if (mQsFullyExpanded && mFalsingManager.shouldEnforceBouncer()) {
|
||||
mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
|
||||
false /* dismissShade */, true /* afterKeyguardGone */);
|
||||
}
|
||||
@@ -1839,7 +1838,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
protected void onTrackingStarted() {
|
||||
mLockedPhoneAnalytics.onTrackingStarted();
|
||||
mFalsingManager.onTrackingStarted();
|
||||
super.onTrackingStarted();
|
||||
if (mQsFullyExpanded) {
|
||||
mQsExpandImmediate = true;
|
||||
@@ -1853,7 +1852,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
protected void onTrackingStopped(boolean expand) {
|
||||
mLockedPhoneAnalytics.onTrackingStopped();
|
||||
mFalsingManager.onTrackingStopped();
|
||||
super.onTrackingStopped(expand);
|
||||
if (expand) {
|
||||
mNotificationStackScroller.setOverScrolledPixels(
|
||||
@@ -1953,8 +1952,8 @@ public class NotificationPanelView extends PanelView implements
|
||||
EventLogTags.writeSysuiLockscreenGesture(
|
||||
EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER, lengthDp, velocityDp);
|
||||
|
||||
mLockedPhoneAnalytics.onLeftAffordanceOn();
|
||||
if (mLockedPhoneAnalytics.shouldEnforceBouncer()) {
|
||||
mFalsingManager.onLeftAffordanceOn();
|
||||
if (mFalsingManager.shouldEnforceBouncer()) {
|
||||
mStatusBar.executeRunnableDismissingKeyguard(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -1969,8 +1968,8 @@ public class NotificationPanelView extends PanelView implements
|
||||
EventLogTags.writeSysuiLockscreenGesture(
|
||||
EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA, lengthDp, velocityDp);
|
||||
|
||||
mLockedPhoneAnalytics.onCameraOn();
|
||||
if (mLockedPhoneAnalytics.shouldEnforceBouncer()) {
|
||||
mFalsingManager.onCameraOn();
|
||||
if (mFalsingManager.shouldEnforceBouncer()) {
|
||||
mStatusBar.executeRunnableDismissingKeyguard(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -2024,7 +2023,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
public void onSwipingStarted(boolean rightIcon) {
|
||||
mLockedPhoneAnalytics.onAffordanceSwipingStarted(rightIcon);
|
||||
mFalsingManager.onAffordanceSwipingStarted(rightIcon);
|
||||
boolean camera = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? !rightIcon
|
||||
: rightIcon;
|
||||
if (camera) {
|
||||
@@ -2037,7 +2036,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
public void onSwipingAborted() {
|
||||
mLockedPhoneAnalytics.onAffordanceSwipingAborted();
|
||||
mFalsingManager.onAffordanceSwipingAborted();
|
||||
mKeyguardBottomArea.unbindCameraPrewarmService(false /* launched */);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ import android.widget.FrameLayout;
|
||||
import com.android.systemui.EventLogConstants;
|
||||
import com.android.systemui.EventLogTags;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.Classifier;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
import com.android.systemui.classifier.HumanInteractionClassifier;
|
||||
import com.android.systemui.doze.DozeLog;
|
||||
import com.android.systemui.statusbar.FlingAnimationUtils;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
@@ -85,6 +88,7 @@ public abstract class PanelView extends FrameLayout {
|
||||
private ObjectAnimator mPeekAnimator;
|
||||
private VelocityTrackerInterface mVelocityTracker;
|
||||
private FlingAnimationUtils mFlingAnimationUtils;
|
||||
private FalsingManager mFalsingManager;
|
||||
|
||||
/**
|
||||
* Whether an instant expand request is currently pending and we are just waiting for layout.
|
||||
@@ -190,6 +194,7 @@ public abstract class PanelView extends FrameLayout {
|
||||
mLinearOutSlowInInterpolator =
|
||||
AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
|
||||
mBounceInterpolator = new BounceInterpolator();
|
||||
mFalsingManager = FalsingManager.getInstance(context);
|
||||
}
|
||||
|
||||
protected void loadDimens() {
|
||||
@@ -605,6 +610,9 @@ public abstract class PanelView extends FrameLayout {
|
||||
if (!mStatusBar.isFalsingThresholdNeeded()) {
|
||||
return false;
|
||||
}
|
||||
if (mFalsingManager.isFalseTouch(Classifier.UNLOCK)) {
|
||||
return true;
|
||||
}
|
||||
if (!mTouchAboveFalsingThreshold) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ import com.android.systemui.EventLogConstants;
|
||||
import com.android.systemui.EventLogTags;
|
||||
import com.android.systemui.Prefs;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
import com.android.systemui.assist.AssistManager;
|
||||
import com.android.systemui.doze.DozeHost;
|
||||
import com.android.systemui.doze.DozeLog;
|
||||
@@ -131,7 +132,6 @@ 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;
|
||||
@@ -598,7 +598,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
private HashSet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new HashSet<>();
|
||||
private RankingMap mLatestRankingMap;
|
||||
private boolean mNoAnimationOnNextBarModeChange;
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
private FalsingManager mFalsingManager;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
@@ -646,7 +646,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
notifyUserAboutHiddenNotifications();
|
||||
|
||||
mScreenPinningRequest = new ScreenPinningRequest(mContext);
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(mContext);
|
||||
mFalsingManager = FalsingManager.getInstance(mContext);
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
@@ -3805,7 +3805,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
mState = state;
|
||||
mGroupManager.setStatusBarState(state);
|
||||
mLockedPhoneAnalytics.setStatusBarState(state);
|
||||
mFalsingManager.setStatusBarState(state);
|
||||
mStatusBarWindowManager.setStatusBarState(state);
|
||||
updateDozing();
|
||||
}
|
||||
@@ -3827,7 +3827,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
|
||||
public void onUnlockHintStarted() {
|
||||
mLockedPhoneAnalytics.onUnlockHintStarted();
|
||||
mFalsingManager.onUnlockHintStarted();
|
||||
mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
|
||||
}
|
||||
|
||||
@@ -3837,17 +3837,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
|
||||
public void onCameraHintStarted() {
|
||||
mLockedPhoneAnalytics.onCameraHintStarted();
|
||||
mFalsingManager.onCameraHintStarted();
|
||||
mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
|
||||
}
|
||||
|
||||
public void onVoiceAssistHintStarted() {
|
||||
mLockedPhoneAnalytics.onLeftAffordanceHintStarted();
|
||||
mFalsingManager.onLeftAffordanceHintStarted();
|
||||
mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
|
||||
}
|
||||
|
||||
public void onPhoneHintStarted() {
|
||||
mLockedPhoneAnalytics.onLeftAffordanceHintStarted();
|
||||
mFalsingManager.onLeftAffordanceHintStarted();
|
||||
mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
|
||||
}
|
||||
|
||||
@@ -3922,7 +3922,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
row.setUserExpanded(true);
|
||||
}
|
||||
boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
|
||||
|| !mShowLockscreenNotifications || mLockedPhoneAnalytics.shouldEnforceBouncer();
|
||||
|| !mShowLockscreenNotifications || mFalsingManager.shouldEnforceBouncer();
|
||||
if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
|
||||
mLeaveOpenOnKeyguardHide = true;
|
||||
showBouncer();
|
||||
@@ -3970,7 +3970,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mDeviceInteractive = false;
|
||||
mWakeUpComingFromTouch = false;
|
||||
mWakeUpTouchLocation = null;
|
||||
mLockedPhoneAnalytics.onScreenOff();
|
||||
mFalsingManager.onScreenOff();
|
||||
mStackScroller.setAnimationsEnabled(false);
|
||||
updateVisibleToUser();
|
||||
}
|
||||
@@ -3980,11 +3980,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mStackScroller.setAnimationsEnabled(true);
|
||||
mNotificationPanel.setTouchDisabled(false);
|
||||
updateVisibleToUser();
|
||||
mLockedPhoneAnalytics.onScreenOn();
|
||||
}
|
||||
|
||||
public void onScreenTurningOn() {
|
||||
mScreenTurningOn = true;
|
||||
mFalsingManager.onScreenTurningOn();
|
||||
mNotificationPanel.onScreenTurningOn();
|
||||
if (mLaunchCameraOnScreenTurningOn) {
|
||||
mNotificationPanel.launchCamera(false);
|
||||
@@ -4119,7 +4119,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
|
||||
mNotificationPanel.setTouchDisabled(false);
|
||||
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
|
||||
mLockedPhoneAnalytics.onScreenOnFromTouch();
|
||||
mFalsingManager.onScreenOnFromTouch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@ import android.view.WindowManagerGlobal;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
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;
|
||||
|
||||
|
||||
@@ -56,14 +56,14 @@ public class StatusBarWindowView extends FrameLayout {
|
||||
|
||||
private PhoneStatusBar mService;
|
||||
private final Paint mTransparentSrcPaint = new Paint();
|
||||
private LockedPhoneAnalytics mLockedPhoneAnalytics;
|
||||
private FalsingManager mFalsingManager;
|
||||
|
||||
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);
|
||||
mFalsingManager = FalsingManager.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,7 +200,7 @@ public class StatusBarWindowView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
mLockedPhoneAnalytics.onTouchEvent(ev, getWidth(), getHeight());
|
||||
mFalsingManager.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
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.widget.OverScroller;
|
||||
import com.android.systemui.ExpandHelper;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SwipeHelper;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
import com.android.systemui.statusbar.ActivatableNotificationView;
|
||||
import com.android.systemui.statusbar.DismissView;
|
||||
import com.android.systemui.statusbar.EmptyShadeView;
|
||||
@@ -47,7 +48,6 @@ 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;
|
||||
@@ -232,7 +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;
|
||||
private FalsingManager mFalsingManager;
|
||||
|
||||
public NotificationStackScrollLayout(Context context) {
|
||||
this(context, null);
|
||||
@@ -266,7 +266,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
mDebugPaint.setStrokeWidth(2);
|
||||
mDebugPaint.setStyle(Paint.Style.STROKE);
|
||||
}
|
||||
mLockedPhoneAnalytics = LockedPhoneAnalytics.getInstance(context);
|
||||
mFalsingManager = FalsingManager.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -599,8 +599,8 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
if (DEBUG) Log.v(TAG, "onChildDismissed: " + v);
|
||||
|
||||
mLockedPhoneAnalytics.onNotificationDismissed();
|
||||
if (mLockedPhoneAnalytics.shouldEnforceBouncer()) {
|
||||
mFalsingManager.onNotificationDismissed();
|
||||
if (mFalsingManager.shouldEnforceBouncer()) {
|
||||
mPhoneStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
|
||||
false /* dismissShade */, true /* afterKeyguardGone */);
|
||||
}
|
||||
@@ -631,7 +631,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
|
||||
public void onBeginDrag(View v) {
|
||||
mLockedPhoneAnalytics.onNotificatonStartDismissing();
|
||||
mFalsingManager.onNotificatonStartDismissing();
|
||||
setSwipingInProgress(true);
|
||||
mAmbientState.onBeginDrag(v);
|
||||
if (mAnimationsEnabled && (mIsExpanded || !isPinnedHeadsUp(v))) {
|
||||
@@ -658,7 +658,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
|
||||
public void onDragCancelled(View v) {
|
||||
mLockedPhoneAnalytics.onNotificatonStopDismissing();
|
||||
mFalsingManager.onNotificatonStopDismissing();
|
||||
setSwipingInProgress(false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user