blob: 2644bf9f26ce78797d940e23a4e05c25631a1fae [file] [log] [blame]
Dave Mankoff8bfbe332019-06-12 17:58:30 -04001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.classifier.brightline;
18
Dave Mankoff8756e452019-07-18 17:20:11 -040019import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
Dave Mankoff8bfbe332019-06-12 17:58:30 -040020import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
21
22import android.hardware.Sensor;
23import android.hardware.SensorEvent;
Dave Mankoff8756e452019-07-18 17:20:11 -040024import android.provider.DeviceConfig;
Dave Mankoff8bfbe332019-06-12 17:58:30 -040025import android.view.MotionEvent;
26
27
28/**
29 * False touch if proximity sensor is covered for more than a certain percentage of the gesture.
30 *
31 * This classifer is essentially a no-op for QUICK_SETTINGS, as we assume the sensor may be
32 * covered when swiping from the top.
33 */
34class ProximityClassifier extends FalsingClassifier {
35
Dave Mankoff8756e452019-07-18 17:20:11 -040036 private static final float PERCENT_COVERED_THRESHOLD = 0.1f;
Dave Mankoff8bfbe332019-06-12 17:58:30 -040037 private final DistanceClassifier mDistanceClassifier;
Dave Mankoff8756e452019-07-18 17:20:11 -040038 private final float mPercentCoveredThreshold;
Dave Mankoff8bfbe332019-06-12 17:58:30 -040039
40 private boolean mNear;
41 private long mGestureStartTimeNs;
42 private long mPrevNearTimeNs;
43 private long mNearDurationNs;
44 private float mPercentNear;
45
46 ProximityClassifier(DistanceClassifier distanceClassifier,
47 FalsingDataProvider dataProvider) {
48 super(dataProvider);
49 this.mDistanceClassifier = distanceClassifier;
Dave Mankoff8756e452019-07-18 17:20:11 -040050
51 mPercentCoveredThreshold = DeviceConfig.getFloat(
52 DeviceConfig.NAMESPACE_SYSTEMUI,
53 BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD,
54 PERCENT_COVERED_THRESHOLD);
Dave Mankoff8bfbe332019-06-12 17:58:30 -040055 }
56
57 @Override
58 void onSessionStarted() {
59 mPrevNearTimeNs = 0;
60 mPercentNear = 0;
61 }
62
63 @Override
64 void onSessionEnded() {
65 mPrevNearTimeNs = 0;
66 mPercentNear = 0;
67 }
68
69 @Override
70 public void onTouchEvent(MotionEvent motionEvent) {
71 int action = motionEvent.getActionMasked();
72
73 if (action == MotionEvent.ACTION_DOWN) {
74 mGestureStartTimeNs = motionEvent.getEventTimeNano();
75 if (mPrevNearTimeNs > 0) {
76 // We only care about if the proximity sensor is triggered while a move event is
77 // happening.
78 mPrevNearTimeNs = motionEvent.getEventTimeNano();
79 }
80 logDebug("Gesture start time: " + mGestureStartTimeNs);
81 mNearDurationNs = 0;
82 }
83
84 if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
85 update(mNear, motionEvent.getEventTimeNano());
86 long duration = motionEvent.getEventTimeNano() - mGestureStartTimeNs;
87
88 logDebug("Gesture duration, Proximity duration: " + duration + ", " + mNearDurationNs);
89
90 if (duration == 0) {
91 mPercentNear = mNear ? 1.0f : 0.0f;
92 } else {
93 mPercentNear = (float) mNearDurationNs / (float) duration;
94 }
95 }
96
97 }
98
99 @Override
100 public void onSensorEvent(SensorEvent sensorEvent) {
101 if (sensorEvent.sensor.getType() == Sensor.TYPE_PROXIMITY) {
102 logDebug("Sensor is: " + (sensorEvent.values[0] < sensorEvent.sensor.getMaximumRange())
103 + " at time " + sensorEvent.timestamp);
104 update(
105 sensorEvent.values[0] < sensorEvent.sensor.getMaximumRange(),
106 sensorEvent.timestamp);
107 }
108 }
109
110 @Override
111 public boolean isFalseTouch() {
112 if (getInteractionType() == QUICK_SETTINGS) {
113 return false;
114 }
115
116 logInfo("Percent of gesture in proximity: " + mPercentNear);
117
Dave Mankoff8756e452019-07-18 17:20:11 -0400118 if (mPercentNear > mPercentCoveredThreshold) {
Dave Mankoff8bfbe332019-06-12 17:58:30 -0400119 return !mDistanceClassifier.isLongSwipe();
120 }
121
122 return false;
123 }
124
125 /**
126 * @param near is the sensor showing the near state right now
127 * @param timeStampNs time of this event in nanoseconds
128 */
129 private void update(boolean near, long timeStampNs) {
130 if (mPrevNearTimeNs != 0 && timeStampNs > mPrevNearTimeNs && mNear) {
131 mNearDurationNs += timeStampNs - mPrevNearTimeNs;
132 logDebug("Updating duration: " + mNearDurationNs);
133 }
134
135 if (near) {
136 logDebug("Set prevNearTimeNs: " + timeStampNs);
137 mPrevNearTimeNs = timeStampNs;
138 }
139
140 mNear = near;
141 }
142}