OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.contextualsearch; | 5 package org.chromium.chrome.browser.contextualsearch; |
6 | 6 |
7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
8 import android.os.Handler; | 8 import android.os.Handler; |
9 import android.text.TextUtils; | 9 import android.text.TextUtils; |
10 import android.view.View; | 10 import android.view.View; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 | 87 |
88 // How long to wait for a tap near a previous tap before hiding the UI or sh
owing a re-Tap. | 88 // How long to wait for a tap near a previous tap before hiding the UI or sh
owing a re-Tap. |
89 // This setting is not critical: in practice it determines how long to wait
after an invalid | 89 // This setting is not critical: in practice it determines how long to wait
after an invalid |
90 // tap for the page to respond before hiding the UI. Specifically this setti
ng just needs to be | 90 // tap for the page to respond before hiding the UI. Specifically this setti
ng just needs to be |
91 // long enough for Blink's decisions before calling handleShowUnhandledTapUI
IfNeeded (which | 91 // long enough for Blink's decisions before calling handleShowUnhandledTapUI
IfNeeded (which |
92 // probably are page-dependent), and short enough that the Bar goes away fai
rly quickly after a | 92 // probably are page-dependent), and short enough that the Bar goes away fai
rly quickly after a |
93 // tap on non-text or whitespace: We currently do not get notification in th
ese cases (hence the | 93 // tap on non-text or whitespace: We currently do not get notification in th
ese cases (hence the |
94 // timer). | 94 // timer). |
95 private static final int TAP_NEAR_PREVIOUS_DETECTION_DELAY_MS = 100; | 95 private static final int TAP_NEAR_PREVIOUS_DETECTION_DELAY_MS = 100; |
96 | 96 |
| 97 private static final int NANOSECONDS_IN_A_MILLISECOND = 1000000; |
| 98 |
97 private final ObserverList<ContextualSearchObserver> mObservers = | 99 private final ObserverList<ContextualSearchObserver> mObservers = |
98 new ObserverList<ContextualSearchObserver>(); | 100 new ObserverList<ContextualSearchObserver>(); |
99 | 101 |
100 private final ChromeActivity mActivity; | 102 private final ChromeActivity mActivity; |
101 private final ContextualSearchTabPromotionDelegate mTabPromotionDelegate; | 103 private final ContextualSearchTabPromotionDelegate mTabPromotionDelegate; |
102 private final ViewTreeObserver.OnGlobalFocusChangeListener mOnFocusChangeLis
tener; | 104 private final ViewTreeObserver.OnGlobalFocusChangeListener mOnFocusChangeLis
tener; |
103 private final TabModelObserver mTabModelObserver; | 105 private final TabModelObserver mTabModelObserver; |
104 | 106 |
| 107 // The Ranker logger to use to write Tap Suppression Ranker logs to UMA. |
| 108 private final ContextualSearchRankerLogger mTapSuppressionRankerLogger; |
| 109 |
105 private ContextualSearchSelectionController mSelectionController; | 110 private ContextualSearchSelectionController mSelectionController; |
106 private ContextualSearchNetworkCommunicator mNetworkCommunicator; | 111 private ContextualSearchNetworkCommunicator mNetworkCommunicator; |
107 private ContextualSearchPolicy mPolicy; | 112 private ContextualSearchPolicy mPolicy; |
108 private ContextualSearchInternalStateController mInternalStateController; | 113 private ContextualSearchInternalStateController mInternalStateController; |
109 | 114 |
110 @VisibleForTesting | 115 @VisibleForTesting |
111 protected ContextualSearchTranslateController mTranslateController; | 116 protected ContextualSearchTranslateController mTranslateController; |
112 | 117 |
113 // The Overlay panel. | 118 // The Overlay panel. |
114 private ContextualSearchPanel mSearchPanel; | 119 private ContextualSearchPanel mSearchPanel; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 @Override | 222 @Override |
218 public void didAddTab(Tab tab, TabLaunchType type) { | 223 public void didAddTab(Tab tab, TabLaunchType type) { |
219 // If we're in the process of promoting this tab, just return an
d don't mess with | 224 // If we're in the process of promoting this tab, just return an
d don't mess with |
220 // this state. | 225 // this state. |
221 if (tab.getContentViewCore() == mSearchPanel.getContentViewCore(
)) return; | 226 if (tab.getContentViewCore() == mSearchPanel.getContentViewCore(
)) return; |
222 hideContextualSearch(StateChangeReason.UNKNOWN); | 227 hideContextualSearch(StateChangeReason.UNKNOWN); |
223 } | 228 } |
224 }; | 229 }; |
225 | 230 |
226 mSelectionController = new ContextualSearchSelectionController(activity,
this); | 231 mSelectionController = new ContextualSearchSelectionController(activity,
this); |
227 | |
228 mNetworkCommunicator = this; | 232 mNetworkCommunicator = this; |
229 | |
230 mPolicy = new ContextualSearchPolicy(mSelectionController, mNetworkCommu
nicator); | 233 mPolicy = new ContextualSearchPolicy(mSelectionController, mNetworkCommu
nicator); |
231 | |
232 mTranslateController = new ContextualSearchTranslateController(activity,
mPolicy, this); | 234 mTranslateController = new ContextualSearchTranslateController(activity,
mPolicy, this); |
233 | |
234 mInternalStateController = new ContextualSearchInternalStateController( | 235 mInternalStateController = new ContextualSearchInternalStateController( |
235 mPolicy, getContextualSearchInternalStateHandler()); | 236 mPolicy, getContextualSearchInternalStateHandler()); |
| 237 mTapSuppressionRankerLogger = new ContextualSearchRankerLoggerImpl(); |
236 } | 238 } |
237 | 239 |
238 /** | 240 /** |
239 * Initializes this manager. | 241 * Initializes this manager. |
240 * @param parentView The parent view to attach Contextual Search UX to. | 242 * @param parentView The parent view to attach Contextual Search UX to. |
241 */ | 243 */ |
242 public void initialize(ViewGroup parentView) { | 244 public void initialize(ViewGroup parentView) { |
243 mNativeContextualSearchManagerPtr = nativeInit(); | 245 mNativeContextualSearchManagerPtr = nativeInit(); |
244 | 246 |
245 mParentView = parentView; | 247 mParentView = parentView; |
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 } | 1286 } |
1285 | 1287 |
1286 @Override | 1288 @Override |
1287 public void handleSuppressedTap() { | 1289 public void handleSuppressedTap() { |
1288 if (mIsAccessibilityModeEnabled) return; | 1290 if (mIsAccessibilityModeEnabled) return; |
1289 | 1291 |
1290 hideContextualSearch(StateChangeReason.BASE_PAGE_TAP); | 1292 hideContextualSearch(StateChangeReason.BASE_PAGE_TAP); |
1291 } | 1293 } |
1292 | 1294 |
1293 @Override | 1295 @Override |
1294 public void handleNonSuppressedTap() { | 1296 public void handleNonSuppressedTap(long tapTimeNanoseconds) { |
1295 if (mIsAccessibilityModeEnabled) return; | 1297 if (mIsAccessibilityModeEnabled) return; |
1296 | 1298 |
1297 mInternalStateController.notifyFinishedWorkOn(InternalState.DECIDING_SUP
PRESSION); | 1299 // If there's a wait-after-tap experiment then we may want to delay a bi
t longer for |
| 1300 // the user to take an action like scrolling that will reset our interna
l state. |
| 1301 long delayBeforeFinishingWorkMs = 0; |
| 1302 if (ContextualSearchFieldTrial.getWaitAfterTapDelayMs() > 0 && tapTimeNa
noseconds > 0) { |
| 1303 delayBeforeFinishingWorkMs = ContextualSearchFieldTrial.getWaitAfter
TapDelayMs() |
| 1304 - (System.nanoTime() - tapTimeNanoseconds) / NANOSECONDS_IN_
A_MILLISECOND; |
| 1305 } |
| 1306 |
| 1307 // Finish work on the current state, either immediately or with a delay. |
| 1308 if (delayBeforeFinishingWorkMs <= 0) { |
| 1309 finishSuppressionDecision(); |
| 1310 } else { |
| 1311 new Handler().postDelayed(new Runnable() { |
| 1312 @Override |
| 1313 public void run() { |
| 1314 finishSuppressionDecision(); |
| 1315 } |
| 1316 }, delayBeforeFinishingWorkMs); |
| 1317 } |
| 1318 } |
| 1319 |
| 1320 /** |
| 1321 * Finishes work on the suppression decision if that work is still in progre
ss. |
| 1322 * If no longer working on the suppression decision then resets the Ranker-l
ogger. |
| 1323 */ |
| 1324 private void finishSuppressionDecision() { |
| 1325 if (mInternalStateController.isStillWorkingOn(InternalState.DECIDING_SUP
PRESSION)) { |
| 1326 mInternalStateController.notifyFinishedWorkOn(InternalState.DECIDING
_SUPPRESSION); |
| 1327 } else { |
| 1328 mTapSuppressionRankerLogger.reset(); |
| 1329 } |
1298 } | 1330 } |
1299 | 1331 |
1300 @Override | 1332 @Override |
1301 public void handleMetricsForWouldSuppressTap(ContextualSearchHeuristics tapH
euristics) { | 1333 public void handleMetricsForWouldSuppressTap(ContextualSearchHeuristics tapH
euristics) { |
1302 mHeuristics = tapHeuristics; | 1334 mHeuristics = tapHeuristics; |
1303 | 1335 |
1304 // TODO(donnd): QuickAnswersHeuristic is getting added to TapSuppression
Heuristics and | 1336 // TODO(donnd): QuickAnswersHeuristic is getting added to TapSuppression
Heuristics and |
1305 // and getting considered in TapSuppressionHeuristics#shouldSuppressTap(
). It should | 1337 // and getting considered in TapSuppressionHeuristics#shouldSuppressTap(
). It should |
1306 // be a part of ContextualSearchHeuristics for logging purposes but not
for suppression. | 1338 // be a part of ContextualSearchHeuristics for logging purposes but not
for suppression. |
1307 mQuickAnswersHeuristic = new QuickAnswersHeuristic(); | 1339 mQuickAnswersHeuristic = new QuickAnswersHeuristic(); |
1308 mHeuristics.add(mQuickAnswersHeuristic); | 1340 mHeuristics.add(mQuickAnswersHeuristic); |
1309 | 1341 |
1310 mSearchPanel.getPanelMetrics().setResultsSeenExperiments(mHeuristics); | 1342 mSearchPanel.getPanelMetrics().setResultsSeenExperiments(mHeuristics); |
1311 mSearchPanel.getPanelMetrics().setRankerLogExperiments(mHeuristics, getB
asePageUrl()); | 1343 mSearchPanel.getPanelMetrics().setRankerLogger(mTapSuppressionRankerLogg
er); |
1312 } | 1344 } |
1313 | 1345 |
1314 @Override | 1346 @Override |
1315 public void handleValidTap() { | 1347 public void handleValidTap() { |
1316 if (mIsAccessibilityModeEnabled) return; | 1348 if (mIsAccessibilityModeEnabled) return; |
1317 | 1349 |
1318 mInternalStateController.enter(InternalState.TAP_RECOGNIZED); | 1350 mInternalStateController.enter(InternalState.TAP_RECOGNIZED); |
1319 } | 1351 } |
1320 | 1352 |
1321 /** | 1353 /** |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 mNativeContextualSearchManagerPtr, mContext, webCont
ents); | 1467 mNativeContextualSearchManagerPtr, mContext, webCont
ents); |
1436 } else { | 1468 } else { |
1437 mInternalStateController.reset(StateChangeReason.UNKNOWN); | 1469 mInternalStateController.reset(StateChangeReason.UNKNOWN); |
1438 } | 1470 } |
1439 } | 1471 } |
1440 | 1472 |
1441 /** Starts the process of deciding if we'll suppress the current Tap
gesture or not. */ | 1473 /** Starts the process of deciding if we'll suppress the current Tap
gesture or not. */ |
1442 @Override | 1474 @Override |
1443 public void decideSuppression() { | 1475 public void decideSuppression() { |
1444 mInternalStateController.notifyStartingWorkOn(InternalState.DECI
DING_SUPPRESSION); | 1476 mInternalStateController.notifyStartingWorkOn(InternalState.DECI
DING_SUPPRESSION); |
1445 mSelectionController.handleShouldSuppressTap(); | 1477 // Ranker will handle the suppression, but our legacy implementa
tion uses |
| 1478 // TapSuppressionHeuristics (run from the ContextualSearchSelect
ionConroller). |
| 1479 mTapSuppressionRankerLogger.setupLoggingForPage(getBasePageUrl()
); |
| 1480 |
| 1481 // TODO(donnd): Move handleShouldSuppressTap out of the Selectio
n Controller. |
| 1482 mSelectionController.handleShouldSuppressTap(mTapSuppressionRank
erLogger); |
1446 } | 1483 } |
1447 | 1484 |
1448 /** Starts showing the Tap UI by selecting a word around the current
caret. */ | 1485 /** Starts showing the Tap UI by selecting a word around the current
caret. */ |
1449 @Override | 1486 @Override |
1450 public void startShowingTapUi() { | 1487 public void startShowingTapUi() { |
1451 WebContents baseWebContents = getBaseWebContents(); | 1488 WebContents baseWebContents = getBaseWebContents(); |
1452 // TODO(donnd): Call isTapSupported earlier so we don't waste ti
me gathering | 1489 // TODO(donnd): Call isTapSupported earlier so we don't waste ti
me gathering |
1453 // surrounding text and deciding suppression when unsupported, o
r remove the whole | 1490 // surrounding text and deciding suppression when unsupported, o
r remove the whole |
1454 // idea of unsupported taps in favor of deciding suppression bet
ter. | 1491 // idea of unsupported taps in favor of deciding suppression bet
ter. |
1455 // Details in crbug.com/715297. | 1492 // Details in crbug.com/715297. |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 private native void nativeStartSearchTermResolutionRequest(long nativeContex
tualSearchManager, | 1633 private native void nativeStartSearchTermResolutionRequest(long nativeContex
tualSearchManager, |
1597 ContextualSearchContext contextualSearchContext, WebContents baseWeb
Contents); | 1634 ContextualSearchContext contextualSearchContext, WebContents baseWeb
Contents); |
1598 protected native void nativeGatherSurroundingText(long nativeContextualSearc
hManager, | 1635 protected native void nativeGatherSurroundingText(long nativeContextualSearc
hManager, |
1599 ContextualSearchContext contextualSearchContext, WebContents baseWeb
Contents); | 1636 ContextualSearchContext contextualSearchContext, WebContents baseWeb
Contents); |
1600 private native void nativeEnableContextualSearchJsApiForOverlay( | 1637 private native void nativeEnableContextualSearchJsApiForOverlay( |
1601 long nativeContextualSearchManager, WebContents overlayWebContents); | 1638 long nativeContextualSearchManager, WebContents overlayWebContents); |
1602 // Don't call these directly, instead call the private methods that cache th
e results. | 1639 // Don't call these directly, instead call the private methods that cache th
e results. |
1603 private native String nativeGetTargetLanguage(long nativeContextualSearchMan
ager); | 1640 private native String nativeGetTargetLanguage(long nativeContextualSearchMan
ager); |
1604 private native String nativeGetAcceptLanguages(long nativeContextualSearchMa
nager); | 1641 private native String nativeGetAcceptLanguages(long nativeContextualSearchMa
nager); |
1605 } | 1642 } |
OLD | NEW |