OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package org.chromium.chrome.browser.contextualsearch; | |
6 | |
7 import android.content.Context; | |
8 | |
9 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; | |
10 | |
11 /** | |
12 * Heuristic for general Tap suppression that factors in a variety of signals. | |
13 */ | |
14 class TapSuppression extends ContextualSearchHeuristic { | |
15 private static final int TIME_THRESHOLD_MILLISECONDS = 3000; | |
pedro (no code reviews)
2016/06/27 22:14:29
The "second tap" is essentially a double tap and I
Donn Denman
2016/06/28 23:39:09
I think we briefly talked with Zach about this and
| |
16 private static final double TAP_TWICE_DISTANCE_SQUARED_DP = Math.pow(30, 2); | |
pedro (no code reviews)
2016/06/27 22:14:29
The "twice" in the name here is confusing, and see
Donn Denman
2016/06/28 23:39:09
Renamed to TAP_RADIUS_SQUARED_DP.
| |
17 | |
18 private final boolean mIsTapSuppressionEnabled; | |
19 private final int mExperimentThresholdTaps; | |
20 private final int mTapsSinceOpen; | |
21 private final float mPxToDp; | |
22 private final boolean mIsSecondTap; | |
23 private final boolean mIsConditionSatisfied; // whether to suppress or not. | |
24 | |
25 /** | |
26 * Constructs a heuristic to decide if a Tap should be suppressed or not. | |
27 * Combines various signals to determine suppression, including whether the previous | |
28 * Tap was suppressed for any reason. | |
29 * @param context The Android Context. | |
30 * @param controller The Selection Controller. | |
31 * @param previousTapState The specifics regarding the previous Tap. | |
32 * @param x The x coordinate of the current tap. | |
33 * @param y The y coordinate of the current tap. | |
34 */ | |
35 TapSuppression(Context context, ContextualSearchSelectionController controll er, | |
36 ContextualSearchTapState previousTapState, int x, int y) { | |
37 mIsSecondTap = previousTapState != null && previousTapState.wasSuppresse d(); | |
Donn Denman
2016/06/28 23:39:09
I think there were some cases where we think we're
| |
38 mIsTapSuppressionEnabled = ContextualSearchFieldTrial.isTapSupressionEna bled(); | |
39 mExperimentThresholdTaps = ContextualSearchFieldTrial.getSuppressionTaps (); | |
40 mPxToDp = controller.getPxToDp(); | |
41 mTapsSinceOpen = ChromePreferenceManager.getInstance(context).getContext ualSearchTapCount(); | |
42 | |
43 boolean doSuppressTap = false; | |
44 if (mIsTapSuppressionEnabled) { | |
45 if (mIsSecondTap) { | |
46 boolean shouldHandle = | |
47 shouldHandleFirstTap() || shouldHandleSecondTap(previous TapState, x, y); | |
48 doSuppressTap = !shouldHandle; | |
49 } else { | |
50 doSuppressTap = !shouldHandleFirstTap(); | |
51 } | |
52 } | |
53 mIsConditionSatisfied = doSuppressTap; | |
54 } | |
55 | |
56 @Override | |
57 protected boolean isConditionSatisfied() { | |
58 return mIsConditionSatisfied; | |
59 } | |
60 | |
61 @Override | |
62 protected void logConditionState() { | |
63 if (mIsTapSuppressionEnabled) { | |
64 ContextualSearchUma.logTapSuppression(mIsConditionSatisfied, mIsSeco ndTap); | |
65 } | |
66 } | |
67 | |
68 @Override | |
69 protected void logResultsSeen(boolean wasSearchContentViewSeen, boolean wasA ctivatedByTap) { | |
70 if (mIsTapSuppressionEnabled) { | |
pedro (no code reviews)
2016/06/27 22:14:29
This will be called even when was triggered by lon
Donn Denman
2016/06/28 23:39:09
Done.
| |
71 ContextualSearchUma.logTapSuppressionResultsSeen( | |
72 wasSearchContentViewSeen, mIsSecondTap); | |
73 } | |
74 } | |
75 | |
76 /** | |
77 * @return whether a first tap should be handled or not. | |
78 */ | |
79 private boolean shouldHandleFirstTap() { | |
80 return mTapsSinceOpen < mExperimentThresholdTaps; | |
81 } | |
82 | |
83 /** | |
84 * Determines whether a second tap at the given coordinates should be handle d. | |
85 * @param tapState The specifics regarding the previous Tap. | |
86 * @param x The x coordinate of the current tap. | |
87 * @param y The y coordinate of the current tap. | |
88 * @return whether a second tap at the given coordinates should be handled o r not. | |
89 */ | |
90 private boolean shouldHandleSecondTap(ContextualSearchTapState tapState, int x, int y) { | |
91 return wasTapCloseToPreviousTap(tapState, x, y); | |
92 } | |
93 | |
94 /** | |
95 * Determines whether a tap at the given coordinates is considered "close" t o the previous | |
96 * tap. | |
97 * @param tapState The specifics regarding the previous Tap. | |
98 * @param x The x coordinate of the current tap. | |
99 * @param y The y coordinate of the current tap. | |
100 */ | |
101 private boolean wasTapCloseToPreviousTap(ContextualSearchTapState tapState, int x, int y) { | |
twellington
2016/06/27 18:44:01
nit: can we combine this with the method in TapFar
Donn Denman
2016/06/28 23:39:09
I don't think it's worth combining since we're jus
| |
102 boolean result = false; | |
103 if (System.nanoTime() - tapState.tapTimeNanoseconds() | |
pedro (no code reviews)
2016/06/27 22:14:29
The duration threshold does not belong in a method
Donn Denman
2016/06/28 23:39:09
Done.
| |
104 <= (long) TIME_THRESHOLD_MILLISECONDS * NANOSECONDS_IN_A_MILLISE COND) { | |
105 // Close enough in time, also in space? | |
twellington
2016/06/27 18:44:01
The space is a 30dp square? Are we trying to detec
Donn Denman
2016/06/28 23:39:09
We're trying to determine if the user is tapping i
Donn Denman
2016/06/28 23:39:09
Yes, that was my plan.
| |
106 float deltaXDp = (tapState.x() - x) * mPxToDp; | |
107 float deltaYDp = (tapState.y() - y) * mPxToDp; | |
108 float distanceSquaredDp = deltaXDp * deltaXDp + deltaYDp * deltaYDp; | |
109 result = distanceSquaredDp <= TAP_TWICE_DISTANCE_SQUARED_DP; | |
110 } | |
111 return result; | |
112 } | |
113 } | |
OLD | NEW |