10e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski/* 20e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * Copyright (C) 2015 The Android Open Source Project 30e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * 40e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * Licensed under the Apache License, Version 2.0 (the "License"); 50e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * you may not use this file except in compliance with the License. 60e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * You may obtain a copy of the License at 70e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * 80e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * http://www.apache.org/licenses/LICENSE-2.0 90e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * 100e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * Unless required by applicable law or agreed to in writing, software 110e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * distributed under the License is distributed on an "AS IS" BASIS, 120e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * See the License for the specific language governing permissions and 140e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * limitations under the License 150e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski */ 160e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 170e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskipackage com.android.systemui.classifier; 180e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 190e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport android.content.Context; 200e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport android.database.ContentObserver; 210e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport android.hardware.SensorEvent; 220e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport android.os.Handler; 230e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport android.os.UserHandle; 240e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport android.provider.Settings; 2591be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowskiimport android.util.DisplayMetrics; 26401caaedd871894620accc1d14592c08095b5523Adrian Roosimport android.util.Log; 270e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport android.view.MotionEvent; 280e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 2991be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowskiimport java.util.ArrayDeque; 309f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowskiimport java.util.ArrayList; 319f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 320e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski/** 330e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski * An classifier trying to determine whether it is a human interacting with the phone or not. 340e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski */ 350e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskipublic class HumanInteractionClassifier extends Classifier { 360e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski private static final String HIC_ENABLE = "HIC_enable"; 3791be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski private static final float FINGER_DISTANCE = 0.1f; 385c42df13a457abc99926e4b1a6aa4d45af3719c7Adrian Roos 395c42df13a457abc99926e4b1a6aa4d45af3719c7Adrian Roos /** Default value for the HIC_ENABLE setting: 1 - enabled, 0 - disabled */ 405c42df13a457abc99926e4b1a6aa4d45af3719c7Adrian Roos private static final int HIC_ENABLE_DEFAULT = 1; 415c42df13a457abc99926e4b1a6aa4d45af3719c7Adrian Roos 420e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski private static HumanInteractionClassifier sInstance = null; 430e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 440e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski private final Handler mHandler = new Handler(); 450e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski private final Context mContext; 460e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 47401caaedd871894620accc1d14592c08095b5523Adrian Roos private final StrokeClassifier[] mStrokeClassifiers; 48401caaedd871894620accc1d14592c08095b5523Adrian Roos private final GestureClassifier[] mGestureClassifiers; 49401caaedd871894620accc1d14592c08095b5523Adrian Roos private final ArrayDeque<MotionEvent> mBufferedEvents = new ArrayDeque<>(); 50401caaedd871894620accc1d14592c08095b5523Adrian Roos private final HistoryEvaluator mHistoryEvaluator; 5191be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski private final float mDpi; 529f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 5352af6b646bd3abc8223ed01a36f6da785b35085dBlazej Magnowski private boolean mEnableClassifier = false; 549f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski private int mCurrentType = Classifier.GENERIC; 550e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 560e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) { 570e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski @Override 580e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski public void onChange(boolean selfChange) { 590e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski updateConfiguration(); 600e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 610e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski }; 620e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 630e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski private HumanInteractionClassifier(Context context) { 640e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski mContext = context; 6591be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics(); 6691be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski 6791be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // If the phone is rotated to landscape, the calculations would be wrong if xdpi and ydpi 6891be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // were to be used separately. Due negligible differences in xdpi and ydpi we can just 6991be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // take the average. 7056918509c7f4f8ec021de897a732b4bc4859c0b0Adrian Roos // Note that xdpi and ydpi are the physical pixels per inch and are not affected by scaling. 7191be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mDpi = (displayMetrics.xdpi + displayMetrics.ydpi) / 2.0f; 7291be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mClassifierData = new ClassifierData(mDpi); 739f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski mHistoryEvaluator = new HistoryEvaluator(); 749f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 75401caaedd871894620accc1d14592c08095b5523Adrian Roos mStrokeClassifiers = new StrokeClassifier[]{ 76401caaedd871894620accc1d14592c08095b5523Adrian Roos new AnglesClassifier(mClassifierData), 77401caaedd871894620accc1d14592c08095b5523Adrian Roos new SpeedClassifier(mClassifierData), 78401caaedd871894620accc1d14592c08095b5523Adrian Roos new DurationCountClassifier(mClassifierData), 79401caaedd871894620accc1d14592c08095b5523Adrian Roos new EndPointRatioClassifier(mClassifierData), 80401caaedd871894620accc1d14592c08095b5523Adrian Roos new EndPointLengthClassifier(mClassifierData), 81401caaedd871894620accc1d14592c08095b5523Adrian Roos new AccelerationClassifier(mClassifierData), 82401caaedd871894620accc1d14592c08095b5523Adrian Roos new SpeedAnglesClassifier(mClassifierData), 83401caaedd871894620accc1d14592c08095b5523Adrian Roos new LengthCountClassifier(mClassifierData), 84401caaedd871894620accc1d14592c08095b5523Adrian Roos new DirectionClassifier(mClassifierData), 85401caaedd871894620accc1d14592c08095b5523Adrian Roos }; 86401caaedd871894620accc1d14592c08095b5523Adrian Roos 87401caaedd871894620accc1d14592c08095b5523Adrian Roos mGestureClassifiers = new GestureClassifier[] { 88401caaedd871894620accc1d14592c08095b5523Adrian Roos new PointerCountClassifier(mClassifierData), 89401caaedd871894620accc1d14592c08095b5523Adrian Roos new ProximityClassifier(mClassifierData) 90401caaedd871894620accc1d14592c08095b5523Adrian Roos }; 910e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 920e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski mContext.getContentResolver().registerContentObserver( 930e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski Settings.Global.getUriFor(HIC_ENABLE), false, 940e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski mSettingsObserver, 950e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski UserHandle.USER_ALL); 960e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 970e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski updateConfiguration(); 980e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 990e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 1000e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski public static HumanInteractionClassifier getInstance(Context context) { 1010e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski if (sInstance == null) { 1020e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski sInstance = new HumanInteractionClassifier(context); 1030e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 1040e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski return sInstance; 1050e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 1060e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 1070e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski private void updateConfiguration() { 1085c42df13a457abc99926e4b1a6aa4d45af3719c7Adrian Roos mEnableClassifier = 0 != Settings.Global.getInt( 1090e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski mContext.getContentResolver(), 1105c42df13a457abc99926e4b1a6aa4d45af3719c7Adrian Roos HIC_ENABLE, HIC_ENABLE_DEFAULT); 1110e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 1120e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 1139f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski public void setType(int type) { 1149f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski mCurrentType = type; 1159f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski } 1169f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 1170e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski @Override 1180e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski public void onTouchEvent(MotionEvent event) { 11991be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski if (!mEnableClassifier) { 12091be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski return; 12191be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski } 1229f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 123c5584ceaad422c96f978132aee4d21ee1f61fc7dAdrian Roos // If the user is dragging down the notification, they might want to drag it down 12491be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // enough to see the content, read it for a while and then lift the finger to open 12591be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // the notification. This kind of motion scores very bad in the Classifier so the 12691be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // MotionEvents which are close to the current position of the finger are not 12791be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // sent to the classifiers until the finger moves far enough. When the finger if lifted 12891be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // up, the last MotionEvent which was far enough from the finger is set as the final 12991be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski // MotionEvent and sent to the Classifiers. 13091be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski if (mCurrentType == Classifier.NOTIFICATION_DRAG_DOWN) { 13191be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mBufferedEvents.add(MotionEvent.obtain(event)); 13291be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski Point pointEnd = new Point(event.getX() / mDpi, event.getY() / mDpi); 13391be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski 13491be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski while (pointEnd.dist(new Point(mBufferedEvents.getFirst().getX() / mDpi, 13591be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mBufferedEvents.getFirst().getY() / mDpi)) > FINGER_DISTANCE) { 13691be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski addTouchEvent(mBufferedEvents.getFirst()); 13791be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mBufferedEvents.remove(); 1389f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski } 1399f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 14091be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski int action = event.getActionMasked(); 14191be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski if (action == MotionEvent.ACTION_UP) { 14291be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mBufferedEvents.getFirst().setAction(MotionEvent.ACTION_UP); 14391be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski addTouchEvent(mBufferedEvents.getFirst()); 14491be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mBufferedEvents.clear(); 1459f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski } 14691be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski } else { 14791be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski addTouchEvent(event); 14891be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski } 14991be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski } 1509f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 15191be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski private void addTouchEvent(MotionEvent event) { 15291be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mClassifierData.update(event); 1539f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 154401caaedd871894620accc1d14592c08095b5523Adrian Roos for (StrokeClassifier c : mStrokeClassifiers) { 155401caaedd871894620accc1d14592c08095b5523Adrian Roos c.onTouchEvent(event); 15691be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski } 15791be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski 158401caaedd871894620accc1d14592c08095b5523Adrian Roos for (GestureClassifier c : mGestureClassifiers) { 159401caaedd871894620accc1d14592c08095b5523Adrian Roos c.onTouchEvent(event); 16091be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski } 16191be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski 16291be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski int size = mClassifierData.getEndingStrokes().size(); 16391be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski for (int i = 0; i < size; i++) { 16491be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski Stroke stroke = mClassifierData.getEndingStrokes().get(i); 16591be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski float evaluation = 0.0f; 166401caaedd871894620accc1d14592c08095b5523Adrian Roos StringBuilder sb = FalsingLog.ENABLED ? new StringBuilder("stroke") : null; 167401caaedd871894620accc1d14592c08095b5523Adrian Roos for (StrokeClassifier c : mStrokeClassifiers) { 168401caaedd871894620accc1d14592c08095b5523Adrian Roos float e = c.getFalseTouchEvaluation(mCurrentType, stroke); 169401caaedd871894620accc1d14592c08095b5523Adrian Roos if (FalsingLog.ENABLED) { 170401caaedd871894620accc1d14592c08095b5523Adrian Roos String tag = c.getTag(); 171401caaedd871894620accc1d14592c08095b5523Adrian Roos sb.append(" ").append(e >= 1f ? tag : tag.toLowerCase()).append("=").append(e); 172401caaedd871894620accc1d14592c08095b5523Adrian Roos } 173401caaedd871894620accc1d14592c08095b5523Adrian Roos evaluation += e; 174401caaedd871894620accc1d14592c08095b5523Adrian Roos } 175401caaedd871894620accc1d14592c08095b5523Adrian Roos 176401caaedd871894620accc1d14592c08095b5523Adrian Roos if (FalsingLog.ENABLED) { 177401caaedd871894620accc1d14592c08095b5523Adrian Roos FalsingLog.i(" addTouchEvent", sb.toString()); 1789f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski } 17991be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mHistoryEvaluator.addStroke(evaluation); 18091be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski } 1819f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski 18291be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski int action = event.getActionMasked(); 18391be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 18491be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski float evaluation = 0.0f; 185401caaedd871894620accc1d14592c08095b5523Adrian Roos StringBuilder sb = FalsingLog.ENABLED ? new StringBuilder("gesture") : null; 186401caaedd871894620accc1d14592c08095b5523Adrian Roos for (GestureClassifier c : mGestureClassifiers) { 187401caaedd871894620accc1d14592c08095b5523Adrian Roos float e = c.getFalseTouchEvaluation(mCurrentType); 188401caaedd871894620accc1d14592c08095b5523Adrian Roos if (FalsingLog.ENABLED) { 189401caaedd871894620accc1d14592c08095b5523Adrian Roos String tag = c.getTag(); 190401caaedd871894620accc1d14592c08095b5523Adrian Roos sb.append(" ").append(e >= 1f ? tag : tag.toLowerCase()).append("=").append(e); 191401caaedd871894620accc1d14592c08095b5523Adrian Roos } 192401caaedd871894620accc1d14592c08095b5523Adrian Roos evaluation += e; 193401caaedd871894620accc1d14592c08095b5523Adrian Roos } 194401caaedd871894620accc1d14592c08095b5523Adrian Roos if (FalsingLog.ENABLED) { 195401caaedd871894620accc1d14592c08095b5523Adrian Roos FalsingLog.i(" addTouchEvent", sb.toString()); 19691be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski } 19791be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mHistoryEvaluator.addGesture(evaluation); 19891be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski setType(Classifier.GENERIC); 1990e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 20091be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski 20191be2f88a5434f73514f7ce58f35f47a6033265dBlazej Magnowski mClassifierData.cleanUp(event); 2020e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 2030e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 2040e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski @Override 2050e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski public void onSensorChanged(SensorEvent event) { 206401caaedd871894620accc1d14592c08095b5523Adrian Roos for (Classifier c : mStrokeClassifiers) { 207401caaedd871894620accc1d14592c08095b5523Adrian Roos c.onSensorChanged(event); 20868d0c9b1e9f1df04b3a0e1ebb1e7ed4c18994cf3Blazej Magnowski } 20968d0c9b1e9f1df04b3a0e1ebb1e7ed4c18994cf3Blazej Magnowski 210401caaedd871894620accc1d14592c08095b5523Adrian Roos for (Classifier c : mGestureClassifiers) { 211401caaedd871894620accc1d14592c08095b5523Adrian Roos c.onSensorChanged(event); 21268d0c9b1e9f1df04b3a0e1ebb1e7ed4c18994cf3Blazej Magnowski } 2130e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 2140e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 2159f01c5bfa5c1c63e350808c154adfc2953949b15Blazej Magnowski public boolean isFalseTouch() { 2166dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski if (mEnableClassifier) { 217401caaedd871894620accc1d14592c08095b5523Adrian Roos float evaluation = mHistoryEvaluator.getEvaluation(); 218401caaedd871894620accc1d14592c08095b5523Adrian Roos boolean result = evaluation >= 5.0f; 219401caaedd871894620accc1d14592c08095b5523Adrian Roos if (FalsingLog.ENABLED) { 220401caaedd871894620accc1d14592c08095b5523Adrian Roos FalsingLog.i("isFalseTouch", new StringBuilder() 221401caaedd871894620accc1d14592c08095b5523Adrian Roos .append("eval=").append(evaluation).append(" result=") 222401caaedd871894620accc1d14592c08095b5523Adrian Roos .append(result ? 1 : 0).toString()); 223401caaedd871894620accc1d14592c08095b5523Adrian Roos } 224401caaedd871894620accc1d14592c08095b5523Adrian Roos return result; 2256dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski } 2266dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski return false; 2270e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 2280e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski 2290e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski public boolean isEnabled() { 2300e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski return mEnableClassifier; 2310e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski } 232401caaedd871894620accc1d14592c08095b5523Adrian Roos 233401caaedd871894620accc1d14592c08095b5523Adrian Roos @Override 234401caaedd871894620accc1d14592c08095b5523Adrian Roos public String getTag() { 235401caaedd871894620accc1d14592c08095b5523Adrian Roos return "HIC"; 236401caaedd871894620accc1d14592c08095b5523Adrian Roos } 2370e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski} 238