Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3837)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java

Issue 2096203002: [TTS] Basic Tap Suppression functionality. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added compensation for Quick Answers and rebased. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java
new file mode 100644
index 0000000000000000000000000000000000000000..07d6558c773ea3761c6982a979fbefb5f0be76f0
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java
@@ -0,0 +1,95 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.contextualsearch;
+
+/**
+ * Heuristic for general Tap suppression that factors in a variety of signals.
+ */
+class TapSuppression extends ContextualSearchHeuristic {
+ private static final int TIME_THRESHOLD_MILLISECONDS = 3000;
+ private static final int TAP_RADIUS_DPS = 30;
+
+ private final boolean mIsTapSuppressionEnabled;
+ private final int mExperimentThresholdTaps;
+ private final int mTapsSinceOpen;
+ private final float mPxToDp;
+ private final boolean mIsSecondTap;
+ private final boolean mIsConditionSatisfied; // whether to suppress or not.
+
+ /**
+ * Constructs a heuristic to decide if a Tap should be suppressed or not.
+ * Combines various signals to determine suppression, including whether the previous
+ * Tap was suppressed for any reason.
+ * @param controller The Selection Controller.
+ * @param previousTapState The specifics regarding the previous Tap.
+ * @param x The x coordinate of the current tap.
+ * @param y The y coordinate of the current tap.
+ * @param tapsSinceOpen the number of Tap gestures since the last open of the panel.
+ */
+ TapSuppression(ContextualSearchSelectionController controller,
+ ContextualSearchTapState previousTapState, int x, int y, int tapsSinceOpen) {
+ mIsTapSuppressionEnabled = ContextualSearchFieldTrial.isTapSuppressionEnabled();
+ mExperimentThresholdTaps = ContextualSearchFieldTrial.getSuppressionTaps();
+ mPxToDp = controller.getPxToDp();
+ mTapsSinceOpen = tapsSinceOpen;
+ mIsSecondTap = previousTapState != null && previousTapState.wasSuppressed()
Theresa 2016/06/29 01:51:57 Could the previous tap have been suppressed for a
Donn Denman 2016/06/29 02:30:36 Yes, it could have for TapFarFromPreviousSuppressi
+ && !shouldHandleFirstTap();
+
+ boolean doSuppressTap = false;
+ if (mIsTapSuppressionEnabled) {
+ if (mIsSecondTap) {
+ boolean shouldHandle = shouldHandleSecondTap(previousTapState, x, y);
+ doSuppressTap = !shouldHandle;
Theresa 2016/06/29 01:51:57 nit: combine with line above?
Donn Denman 2016/06/29 02:30:36 Done.
+ } else {
+ doSuppressTap = !shouldHandleFirstTap();
+ }
+ }
+ mIsConditionSatisfied = doSuppressTap;
+ }
+
+ @Override
+ protected boolean isConditionSatisfied() {
+ return mIsConditionSatisfied;
+ }
+
+ @Override
+ protected void logResultsSeen(boolean wasSearchContentViewSeen, boolean wasActivatedByTap) {
+ // TODO(donnd): consider logging counter-factual data rather than checking if enabled.
+ if (wasActivatedByTap && mIsTapSuppressionEnabled) {
+ ContextualSearchUma.logTapSuppressionResultsSeen(
+ wasSearchContentViewSeen, mIsSecondTap);
+ }
+ }
+
+ /**
+ * @return whether a first tap should be handled or not.
+ */
+ private boolean shouldHandleFirstTap() {
+ return mTapsSinceOpen < mExperimentThresholdTaps;
+ }
+
+ /**
+ * Determines whether a second tap at the given coordinates should be handled.
+ * @param tapState The specifics regarding the previous Tap.
+ * @param x The x coordinate of the current tap.
+ * @param y The y coordinate of the current tap.
+ * @return whether a second tap at the given coordinates should be handled or not.
+ */
+ private boolean shouldHandleSecondTap(ContextualSearchTapState tapState, int x, int y) {
+ // The second tap needs to be close to the first tap in both time and space.
+ // Recent enough?
+ if (System.nanoTime() - tapState.tapTimeNanoseconds()
+ > (long) TIME_THRESHOLD_MILLISECONDS * NANOSECONDS_IN_A_MILLISECOND) {
+ return false;
+ }
+
+ // Within our radius?
+ float deltaXDp = (tapState.getX() - x) * mPxToDp;
+ float deltaYDp = (tapState.getY() - y) * mPxToDp;
+ // Use x^2 * y^2 = r^2
+ float distanceSquaredDp = deltaXDp * deltaXDp + deltaYDp * deltaYDp;
+ return distanceSquaredDp <= TAP_RADIUS_DPS * TAP_RADIUS_DPS;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698